pax_global_header00006660000000000000000000000064137671724130014525gustar00rootroot0000000000000052 comment=c8deb2b4748b941ed772802b499e4f2f491d966f linphone-desktop-4.2.5/000077500000000000000000000000001376717241300150205ustar00rootroot00000000000000linphone-desktop-4.2.5/.gitignore000066400000000000000000000013411376717241300170070ustar00rootroot00000000000000# Temporary files -------------------------------------------------------------- *~ .* \#*\# .#.* # Project configuration -------------------------------------------------------- *.pro.user Project.sln.lnk WORK OUTPUT Makefile CMakeLists.txt.user build-*-Debug build-*-Default prepare.conf.user build/* # Tags ------------------------------------------------------------------------- GPATH GRTAGS GTAGS .ctags .clang_complete # QMLC/JSC --------------------------------------------------------------------- *.qmlc *.jsc # RPM -------------------------------------------------------------------------- linphone-qt/ rpm-*/ # OTHER ------------------------------------------------------------------------ vgcore.* linphone.spec linphone-desktop-4.2.5/.gitlab-ci-files/000077500000000000000000000000001376717241300200315ustar00rootroot00000000000000linphone-desktop-4.2.5/.gitlab-ci-files/job-linux-desktop-archlinux-latest.yml000066400000000000000000000055101376717241300274200ustar00rootroot00000000000000job-archlinux-latest-ninja-clang: tags: [ "docker-archlinux-latest" ] image: gitlab.linphone.org:4567/bc/public/linphone-sdk/bc-dev-archlinux:latest except: refs: - schedules variables: CMAKE_GENERATOR: Ninja CC: clang CXX: clang++ extends: .job-linux-desktop ################################################# # Nightly ################################################# job-archlinux-latest-makefile-gcc: tags: [ "docker-archlinux-latest" ] image: gitlab.linphone.org:4567/bc/public/linphone-sdk/bc-dev-archlinux:latest only: variables: - $NIGHTLY_MASTER variables: CMAKE_GENERATOR: Unix Makefiles CC: gcc CXX: g++ extends: .job-linux-desktop job-archlinux-latest-makefile-clang: tags: [ "docker-archlinux-latest" ] image: gitlab.linphone.org:4567/bc/public/linphone-sdk/bc-dev-archlinux:latest only: variables: - $NIGHTLY_MASTER variables: CMAKE_GENERATOR: Unix Makefiles CC: clang CXX: clang++ extends: .job-linux-desktop job-archlinux-latest-ninja-gcc: tags: [ "docker-archlinux-latest" ] image: gitlab.linphone.org:4567/bc/public/linphone-sdk/bc-dev-archlinux:latest only: variables: - $NIGHTLY_MASTER variables: CMAKE_GENERATOR: Ninja CC: gcc CXX: g++ extends: .job-linux-desktop job-archlinux-latest-ninja-gcc-novideo: tags: [ "docker-archlinux-latest" ] only: variables: - $NIGHTLY_MASTER variables: CMAKE_OPTIONS: -DENABLE_VIDEO=NO extends: job-archlinux-latest-ninja-gcc job-archlinux-latest-ninja-clang-novideo: tags: [ "docker-archlinux-latest" ] image: gitlab.linphone.org:4567/bc/public/linphone-sdk/bc-dev-archlinux:latest only: variables: - $NIGHTLY_MASTER variables: CMAKE_OPTIONS: -DENABLE_VIDEO=NO CMAKE_GENERATOR: Ninja CC: clang CXX: clang++ extends: .job-linux-desktop ################################################# # Package - Nightly ################################################# #job-archlinux-latest-makefile-clang-package: # stage: package # tags: [ "docker-archlinux-latest" ] # only: # variables: # - $NIGHTLY_MASTER # - $DEPLOY_LINUX # variables: # CMAKE_OPTIONS: -DENABLE_APP_PACKAGING=YES # extends: job-archlinux-latest-makefile-clang # artifacts: # paths: # - build/OUTPUT/Packages/Linphone*.AppImage # expire_in: 1 week # ################################################# # Deploy - Nightly ################################################# #job-archlinux-latest-makefile-clang-deploy: # stage: deploy # tags: [ "docker-archlinux-latest" ] # dependencies: # - job-archlinux-latest-makefile-clang-package # only: # variables: # - $NIGHTLY_MASTER # - $DEPLOY_LINUX # script: # - scp build/OUTPUT/Packages/Linphone*.AppImage $DEPLOY_SERVER:$APPIMAGE_UPLOAD_DIRECTORY/ linphone-desktop-4.2.5/.gitlab-ci-files/job-linux-desktop-centos7.yml000066400000000000000000000101751376717241300255160ustar00rootroot00000000000000 #job-centos7-makefile-gcc: # tags: [ "docker" ] # image: gitlab.linphone.org:4567/bc/public/linphone-sdk/bc-dev-centos:7 # only: # variables: # - $NIGHTLY_MASTER # variables: # CMAKE_GENERATOR: Unix Makefiles # CC: gcc # CXX: g++ # extends: .job-linux-desktop #job-centos7-makefile-clang: # tags: [ "docker-centos7" ] # image: gitlab.linphone.org:4567/bc/public/linphone-sdk/bc-dev-centos:7 # only: # variables: # - $NIGHTLY_MASTER # variables: # CMAKE_GENERATOR: Unix Makefiles # CC: clang # CXX: clang++ # extends: .job-linux-desktop ################################################# # Ninja ################################################# job-centos7-ninja-gcc: tags: [ "docker" ] image: gitlab.linphone.org:4567/bc/public/linphone-desktop/bc-dev-centos7-qt-fuse-wget:5.12.5 except: refs: - schedules variables: CMAKE_GENERATOR: Ninja CC: gcc CXX: g++ extends: .job-linux-desktop before_script: - source /opt/rh/devtoolset-8/enable #job-centos7-ninja-clang: # tags: [ "docker-centos7" ] # only: # variables: # - $NIGHTLY_MASTER # image: gitlab.linphone.org:4567/bc/public/linphone-sdk/bc-dev-centos:7 # variables: # CMAKE_GENERATOR: Ninja # CC: clang # CXX: clang++ # CMAKE_OPTIONS: -DENABLE_LIME=ON # extends: .job-linux-desktop ################################################# # Package - Nightly ################################################# job-centos7-ninja-gcc-package: stage: package tags: [ "docker-test-centos7-liblinphone-nuc" ] #image: gitlab.linphone.org:4567/bc/public/linphone-sdk/bc-dev-centos:7 image: gitlab.linphone.org:4567/bc/public/linphone-desktop/bc-dev-centos7-qt-fuse-wget:5.12.5 dependencies: [] only: variables: - $DEPLOY_LINUX_CENTOS7 variables: CMAKE_OPTIONS: -DENABLE_APP_PACKAGING=YES -DLINPHONE_BUILDER_SIGNING_IDENTITY=$GPG_SIGNING_KEYID -DLINPHONE_BUILDER_SIGNING_PASSPHRASE=$GPG_SIGNING_PASS CMAKE_GENERATOR: Ninja CC: gcc CXX: g++ extends: .job-linux-desktop before_script: - source /opt/rh/devtoolset-8/enable script: - echo "$GPG_SIGNING_PUB" > file.key && sed -i 's/\r /\n/g' file.key && chmod 600 file.key - gpg --import file.key - echo "$GPG_SIGNING_KEY" > file.key && sed -i 's/\r /\n/g' file.key && chmod 600 file.key - gpg --import file.key - cmake --version - export CC=$CC - export CXX=$CXX - mkdir -p build/OUTPUT - echo $CI_BUILD_TYPE - echo $CMAKE_GENERATOR - echo $DEFAULT_LINUX_CMAKE_OPTIONS - echo $CMAKE_SANITIZER_OPTIONS - cd build - cmake .. -G "$CMAKE_GENERATOR" -DCMAKE_VERBOSE_MAKEFILE=ON -DLINPHONESDK_PLATFORM=Desktop -DCMAKE_BUILD_TYPE=$CI_BUILD_TYPE $DEFAULT_LINUX_CMAKE_OPTIONS $CMAKE_OPTIONS $SCHEDULE_CMAKE_OPTIONS $CMAKE_SANITIZER_OPTIONS - cmake --build . --target install --config $CI_BUILD_TYPE $LBC_NODEBUG_OPTIONS artifacts: paths: - build/OUTPUT/Packages/*.AppImage expire_in: 1 week ################################################# # Deploy - Nightly ################################################# job-centos7-ninja-gcc-deploy: stage: deploy tags: [ "deploy" ] dependencies: - job-centos7-ninja-gcc-package only: variables: - $DEPLOY_LINUX_CENTOS7 script: - rsync -rlv --ignore-existing build/OUTPUT/Packages/*.AppImage $DEPLOY_SERVER:$APPIMAGE_UPLOAD_DIRECTORY/ ################################################# # Debug ################################################# job-centos7-debug-nuc: stage: deploy tags: [ "docker-test-centos7-liblinphone-nuc" ] #image: gitlab.linphone.org:4567/bc/public/linphone-sdk/bc-dev-centos:7 image: gitlab.linphone.org:4567/bc/public/linphone-desktop/bc-dev-centos7-qt-fuse-wget:5.12.5 dependencies: [] only: variables: - $DEBUG_CENTOS7_NUC script: - sleep 10m job-centos7-debug: stage: deploy tags: [ "docker" ] #image: gitlab.linphone.org:4567/bc/public/linphone-sdk/bc-dev-centos:7 image: gitlab.linphone.org:4567/bc/public/linphone-desktop/bc-dev-centos7-qt-fuse-wget:5.12.5 dependencies: [] only: variables: - $DEBUG_CENTOS7 script: - sleep 10m linphone-desktop-4.2.5/.gitlab-ci-files/job-linux-desktop-debian10.yml000066400000000000000000000060771376717241300255250ustar00rootroot00000000000000 job-debian10-ninja-gcc: tags: [ "docker-debian10" ] image: gitlab.linphone.org:4567/bc/public/linphone-sdk/bc-dev-debian:10 except: refs: - schedules variables: CMAKE_GENERATOR: Ninja CC: gcc CXX: g++ extends: .job-linux-desktop ################################################# # Nightly ################################################# job-debian10-makefile-gcc: tags: [ "docker-debian10" ] image: gitlab.linphone.org:4567/bc/public/linphone-sdk/bc-dev-debian:10 only: variables: - $NIGHTLY_MASTER variables: CMAKE_GENERATOR: Unix Makefiles CC: gcc CXX: g++ ADDITIONAL_BUILD_OPTIONS: -j$MAKEFILE_JOBS extends: .job-linux-desktop job-debian10-ninja-gcc-novideo: tags: [ "docker-debian10" ] image: gitlab.linphone.org:4567/bc/public/linphone-sdk/bc-dev-debian:10 only: variables: - $NIGHTLY_MASTER variables: CMAKE_OPTIONS: -DENABLE_VIDEO=NO CMAKE_GENERATOR: Ninja CC: gcc CXX: g++ extends: .job-linux-desktop job-debian10-ninja-gcc-smallsdk: tags: [ "docker-debian10" ] image: gitlab.linphone.org:4567/bc/public/linphone-sdk/bc-dev-debian:10 only: variables: - $NIGHTLY_MASTER variables: CMAKE_OPTIONS: -DENABLE_VIDEO=NO -DENABLE_ADVANCED_IM=NO -DENABLE_DB_STORAGE=NO CMAKE_GENERATOR: Ninja CC: gcc CXX: g++ extends: .job-linux-desktop job-debian10-ninja-clang: tags: [ "docker-debian10" ] only: variables: - $NIGHTLY_MASTER image: gitlab.linphone.org:4567/bc/public/linphone-sdk/bc-dev-debian:10 variables: CMAKE_GENERATOR: Ninja CC: clang CXX: clang++ extends: .job-linux-desktop job-debian10-ninja-clang-novideo: only: variables: - $NIGHTLY_MASTER variables: CMAKE_OPTIONS: -DENABLE_VIDEO=NO extends: job-debian10-ninja-clang job-debian10-makefile-clang: tags: [ "docker-debian10" ] image: gitlab.linphone.org:4567/bc/public/linphone-sdk/bc-dev-debian:10 only: variables: - $NIGHTLY_MASTER - $DEPLOY_LINUX variables: CMAKE_GENERATOR: Unix Makefiles CC: clang CXX: clang++ ADDITIONAL_BUILD_OPTIONS: -j$MAKEFILE_JOBS extends: .job-linux-desktop ################################################# # Package - Nightly ################################################# job-debian10-makefile-clang-package: stage: package tags: [ "docker-debian10" ] dependencies: [] only: variables: - $NIGHTLY_MASTER - $DEPLOY_LINUX variables: CMAKE_OPTIONS: -DENABLE_APP_PACKAGING=YES extends: job-debian10-makefile-clang artifacts: paths: - build/OUTPUT/Packages/Linphone*.AppImage expire_in: 1 week ################################################# # Deploy - Nightly ################################################# job-debian10-makefile-clang-deploy: stage: deploy tags: [ "docker-debian10" ] dependencies: - job-debian10-makefile-clang-package only: variables: - $NIGHTLY_MASTER - $DEPLOY_LINUX script: - scp build/OUTPUT/Packages/Linphone*.AppImage $DEPLOY_SERVER:$APPIMAGE_UPLOAD_DIRECTORY/ linphone-desktop-4.2.5/.gitlab-ci-files/job-linux-desktop-debian8.yml000066400000000000000000000033661376717241300254520ustar00rootroot00000000000000################################################# # Makefile ################################################# job-debian8-makefile-gcc: tags: [ "docker-debian8" ] image: gitlab.linphone.org:4567/bc/public/linphone-sdk/bc-dev-debian:8 except: refs: - schedules variables: CMAKE_GENERATOR: Unix Makefiles CC: gcc CXX: g++ ADDITIONAL_BUILD_OPTIONS: -j$MAKEFILE_JOBS LBC_NODEBUG_OPTIONS: -- -j$MAKEFILE_JOBS extends: .job-linux-desktop job-debian8-makefile-clang: tags: [ "docker-debian8" ] image: gitlab.linphone.org:4567/bc/public/linphone-sdk/bc-dev-debian:8 only: variables: - $NIGHTLY_MASTER variables: CMAKE_GENERATOR: Unix Makefiles CC: clang CXX: clang++ ADDITIONAL_BUILD_OPTIONS: -j$MAKEFILE_JOBS LBC_NODEBUG_OPTIONS: -- -j$MAKEFILE_JOBS extends: .job-linux-desktop ################################################# # Package - Nightly ################################################# #job-debian8-makefile-clang-package: # stage: package # tags: [ "docker-debian8" ] # only: # variables: # - $NIGHTLY_MASTER # - $DEPLOY_LINUX # variables: # CMAKE_OPTIONS: -DENABLE_APP_PACKAGING=YES # extends: job-debian8-makefile-clang # artifacts: # paths: # - build/OUTPUT/Packages/Linphone*.AppImage # expire_in: 1 week ################################################# # Deploy - Nightly ################################################# #job-debian8-makefile-clang-deploy: # stage: deploy # tags: [ "docker-debian8" ] # dependencies: # - job-debian8-makefile-clang-package # only: # variables: # - $NIGHTLY_MASTER # - $DEPLOY_LINUX # script: # - scp build/OUTPUT/Packages/Linphone*.AppImage $DEPLOY_SERVER:$APPIMAGE_UPLOAD_DIRECTORY/ linphone-desktop-4.2.5/.gitlab-ci-files/job-linux-desktop-debian9.yml000066400000000000000000000110461376717241300254450ustar00rootroot00000000000000 job-debian9-ninja-gcc: tags: [ "docker-debian9" ] image: gitlab.linphone.org:4567/bc/public/linphone-desktop/bc-dev-debian9-fuse-wget-gpg2-qt-release-no-debug-info:5.12.5 except: refs: - schedules variables: CMAKE_GENERATOR: Ninja CC: gcc CXX: g++ extends: .job-linux-desktop job-debian9-ninja-gcc-smallsdk: except: refs: - schedules variables: CMAKE_OPTIONS: -DENABLE_VIDEO=NO -DENABLE_ADVANCED_IM=NO -DENABLE_DB_STORAGE=NO extends: job-debian9-ninja-gcc ################################################# # Nightly ################################################# job-debian9-makefile-gcc: tags: [ "docker-debian9" ] image: gitlab.linphone.org:4567/bc/public/linphone-desktop/bc-dev-debian9-fuse-wget-gpg2-qt-release-no-debug-info:5.12.5 only: variables: - $NIGHTLY_MASTER variables: CMAKE_GENERATOR: Unix Makefiles CC: gcc CXX: g++ ADDITIONAL_BUILD_OPTIONS: -j$MAKEFILE_JOBS extends: .job-linux-desktop job-debian9-ninja-gcc-novideo: only: variables: - $NIGHTLY_MASTER variables: CMAKE_OPTIONS: -DENABLE_VIDEO=NO extends: job-debian9-ninja-gcc job-debian9-ninja-clang: tags: [ "docker-debian9" ] only: variables: - $NIGHTLY_MASTER image: gitlab.linphone.org:4567/bc/public/linphone-desktop/bc-dev-debian9-fuse-wget-gpg2-qt-release-no-debug-info:5.12.5 variables: CMAKE_OPTIONS: -DENABLE_DOC=ON CMAKE_GENERATOR: Ninja CC: clang CXX: clang++ extends: .job-linux-desktop job-debian9-ninja-clang-novideo: only: variables: - $NIGHTLY_MASTER variables: CMAKE_OPTIONS: -DENABLE_VIDEO=NO extends: job-debian9-ninja-clang job-debian9-makefile-clang: tags: [ "docker-debian9" ] image: gitlab.linphone.org:4567/bc/public/linphone-desktop/bc-dev-debian9-fuse-wget-gpg2-qt-release-no-debug-info:5.12.5 only: variables: - $NIGHTLY_MASTER variables: CMAKE_GENERATOR: Unix Makefiles CC: clang CXX: clang++ ADDITIONAL_BUILD_OPTIONS: -j$MAKEFILE_JOBS extends: .job-linux-desktop ################################################# # Package - Nightly ################################################# job-debian9-makefile-clang-package: stage: package tags: [ "docker-test-debian9-liblinphone-nuc" ] image: gitlab.linphone.org:4567/bc/public/linphone-desktop/bc-dev-debian9-fuse-wget-gpg2-qt-release-no-debug-info:5.12.5 dependencies: [] only: variables: - $NIGHTLY_MASTER - $DEPLOY_LINUX variables: CMAKE_OPTIONS: -DENABLE_APP_PACKAGING=YES -DLINPHONE_BUILDER_SIGNING_IDENTITY=$GPG_SIGNING_KEYID -DLINPHONE_BUILDER_SIGNING_PASSPHRASE=$GPG_SIGNING_PASS CMAKE_GENERATOR: Unix Makefiles CC: clang CXX: clang++ extends: .job-linux-desktop script: - echo "$GPG_SIGNING_PUB" > file.key && sed -i 's/\r /\n/g' file.key && chmod 600 file.key - gpg --import file.key - rm -f file.key - echo "$GPG_SIGNING_KEY" > file.key && sed -i 's/\r /\n/g' file.key && chmod 600 file.key - base64 -w 0 file.key | base64 -d | gpg --import --no-tty --batch --yes - rm -f file.key - cmake --version - export CC=$CC - export CXX=$CXX - mkdir -p build/OUTPUT - echo $CI_BUILD_TYPE - echo $CMAKE_GENERATOR - echo $DEFAULT_LINUX_CMAKE_OPTIONS - echo $CMAKE_SANITIZER_OPTIONS - cd build - cmake .. -G "$CMAKE_GENERATOR" -DCMAKE_VERBOSE_MAKEFILE=ON -DLINPHONESDK_PLATFORM=Desktop -DCMAKE_BUILD_TYPE=$CI_BUILD_TYPE $DEFAULT_LINUX_CMAKE_OPTIONS $CMAKE_OPTIONS $SCHEDULE_CMAKE_OPTIONS $CMAKE_SANITIZER_OPTIONS - cmake --build . --target install --config $CI_BUILD_TYPE $LBC_NODEBUG_OPTIONS artifacts: paths: - build/OUTPUT/Packages/*.AppImage expire_in: 1 week ################################################# # Deploy - Nightly ################################################# job-debian9-makefile-clang-deploy: stage: deploy tags: [ "deploy" ] dependencies: - job-debian9-makefile-clang-package only: variables: - $NIGHTLY_MASTER - $DEPLOY_LINUX script: - rsync -rlv --ignore-existing build/OUTPUT/Packages/*.AppImage $DEPLOY_SERVER:$APPIMAGE_UPLOAD_DIRECTORY/ ################################################# # Debug ################################################# job-debian9-debug: stage: deploy tags: [ "docker-test-debian9-liblinphone-nuc" ] image: gitlab.linphone.org:4567/bc/public/linphone-desktop/bc-dev-debian9-fuse-wget-gpg2-qt-release-no-debug-info:5.12.5 dependencies: [] only: variables: - $DEBUG_DEBIAN9 script: - sleep 10m linphone-desktop-4.2.5/.gitlab-ci-files/job-linux-desktop-ubuntu-rolling.yml000066400000000000000000000052641376717241300271250ustar00rootroot00000000000000 job-ubuntu-rolling-ninja-clang: tags: [ "docker-ubuntu-rolling" ] image: gitlab.linphone.org:4567/bc/public/linphone-sdk/bc-dev-ubuntu:rolling except: refs: - schedules variables: CMAKE_GENERATOR: Ninja CC: clang CXX: clang++ extends: .job-linux-desktop ################################################# # Nightly ################################################# job-ubuntu-rolling-makefile-gcc: tags: [ "docker-ubuntu-rolling" ] image: gitlab.linphone.org:4567/bc/public/linphone-sdk/bc-dev-ubuntu:rolling only: variables: - $NIGHTLY_MASTER variables: CMAKE_GENERATOR: Unix Makefiles CC: gcc CXX: g++ ADDITIONAL_BUILD_OPTIONS: -j$MAKEFILE_JOBS extends: .job-linux-desktop job-ubuntu-rolling-makefile-clang: tags: [ "docker-ubuntu-rolling" ] image: gitlab.linphone.org:4567/bc/public/linphone-sdk/bc-dev-ubuntu:rolling only: variables: - $NIGHTLY_MASTER variables: CMAKE_GENERATOR: Unix Makefiles CC: clang CXX: clang++ ADDITIONAL_BUILD_OPTIONS: -j$MAKEFILE_JOBS extends: .job-linux-desktop job-ubuntu-rolling-ninja-gcc: tags: [ "docker-ubuntu-rolling" ] image: gitlab.linphone.org:4567/bc/public/linphone-sdk/bc-dev-ubuntu:rolling only: variables: - $NIGHTLY_MASTER variables: CMAKE_GENERATOR: Ninja CC: gcc CXX: g++ extends: .job-linux-desktop job-ubuntu-rolling-ninja-gcc-novideo: only: variables: - $NIGHTLY_MASTER variables: CMAKE_OPTIONS: -DENABLE_VIDEO=NO extends: job-ubuntu-rolling-ninja-gcc job-ubuntu-rolling-ninja-clang-novideo: only: variables: - $NIGHTLY_MASTER variables: CMAKE_OPTIONS: -DENABLE_VIDEO=NO extends: job-ubuntu-rolling-ninja-clang ################################################# # Package - Nightly ################################################# #job-ubuntu-rolling-makefile-clang-package: # stage: package # tags: [ "docker-ubuntu-rolling" ] # only: # variables: # - $NIGHTLY_MASTER # - $DEPLOY_LINUX # variables: # CMAKE_OPTIONS: -DENABLE_APP_PACKAGING=YES # extends: job-ubuntu-rolling-makefile-clang # artifacts: # paths: # - build/OUTPUT/Packages/Linphone*.AppImage # expire_in: 1 week ################################################# # Deploy - Nightly ################################################# #job-ubuntu-rolling-makefile-clang-deploy: # stage: deploy # tags: [ "docker-ubuntu-rolling" ] # dependencies: # - job-ubuntu-rolling-makefile-clang-package # only: # variables: # - $NIGHTLY_MASTER # - $DEPLOY_LINUX # script: # - scp build/OUTPUT/Packages/Linphone*.AppImage $DEPLOY_SERVER:$APPIMAGE_UPLOAD_DIRECTORY/ linphone-desktop-4.2.5/.gitlab-ci-files/job-linux-desktop.yml000066400000000000000000000015001376717241300241260ustar00rootroot00000000000000################################################# # BUILD ################################################# .build_all_linux_script: &build_all_linux_script | cmake --version export CC=$CC export CXX=$CXX mkdir -p build/OUTPUT echo $CI_BUILD_TYPE echo $CMAKE_GENERATOR echo $DEFAULT_LINUX_CMAKE_OPTIONS echo $CMAKE_SANITIZER_OPTIONS cd build cmake .. -G "$CMAKE_GENERATOR" -DCMAKE_VERBOSE_MAKEFILE=ON -DLINPHONESDK_PLATFORM=Desktop -DCMAKE_BUILD_TYPE=$CI_BUILD_TYPE $DEFAULT_LINUX_CMAKE_OPTIONS $CMAKE_OPTIONS $SCHEDULE_CMAKE_OPTIONS $CMAKE_SANITIZER_OPTIONS cmake --build . --target install --config $CI_BUILD_TYPE $LBC_NODEBUG_OPTIONS .job-linux-desktop: stage: build extends: .linux-prepare script: - *build_all_linux_script artifacts: paths: - build/OUTPUT expire_in: 1 week linphone-desktop-4.2.5/.gitlab-ci-files/job-linux-prepare.yml000066400000000000000000000017621376717241300241250ustar00rootroot00000000000000.linux-prepare: cache: key: $CI_JOB_NAME paths: - ccache/ extends: .job-prepare before_script: ## ## If a TUNNEL_USER_KEY is defined then start ssh-agent and add the key ## - if ! [ -z ${TUNNEL_USER_KEY+x} ]; then eval $(ssh-agent -s); fi - if ! [ -z ${TUNNEL_USER_KEY+x} ]; then echo "$TUNNEL_USER_KEY" | tr -d '\r' | ssh-add - > /dev/null; fi - if ! [ -z ${TUNNEL_USER_KEY+x} ]; then mkdir -p ~/.ssh && chmod 700 ~/.ssh; fi - if ! [ -z ${TUNNEL_USER_KEY+x} ]; then echo -e "Host gitlab.linphone.org\n\tStrictHostKeyChecking no\n\n" > ~/.ssh/config; fi ## ## Then configure ccache ## - mkdir -p ccache - echo "max_size = $CCACHE_SIZE" > ccache/ccache.conf - echo $CCACHE_SIZE - echo ${PWD}/ccache - export CCACHE_BASEDIR=${PWD} - export CCACHE_DIR=${PWD}/ccache - ccache -s after_script: - if ! [ -z ${TUNNEL_USER_KEY+x} ]; then rm -rf ~/.ssh || true; fi - export CCACHE_DIR=${PWD}/ccache - ccache -s linphone-desktop-4.2.5/.gitlab-ci-files/job-macosx-desktop.yml000066400000000000000000000064571376717241300243010ustar00rootroot00000000000000#Build template to use in other job scripts without having to copy same code #format = .className: &referenceName | scripts #Use = scripts: -*referenceName #Example : see .job-macosx-desktop for the default script and job-macosx-makefile-package for override .build_all_script: &build_all_script | ccache -s export Qt5_DIR=/usr/local/opt/qt/lib/cmake export PATH=$PATH:/usr/local/opt/qt/bin if [ -d "build" ]; then rm -rf build; fi; mkdir -p build/OUTPUT cd build #SDK Building echo $CI_BUILD_TYPE echo $CMAKE_GENERATOR echo $DEFAULT_MACOS_CMAKE_OPTIONS echo $CMAKE_OPTIONS echo $ADDITIONAL_BUILD_OPTIONS cmake .. -G "$CMAKE_GENERATOR" -DLINPHONESDK_PLATFORM=Desktop -DCMAKE_OSX_DEPLOYMENT_TARGET=10.9 -DCMAKE_BUILD_TYPE=$CI_BUILD_TYPE $DEFAULT_MACOS_CMAKE_OPTIONS $XCODE_OPTIONS $CMAKE_OPTIONS $SCHEDULE_CMAKE_OPTIONS -DLINPHONE_BUILDER_SIGNING_IDENTITY="$MACOS_SIGNING_IDENTITY" cmake --build . --target install --config $CI_BUILD_TYPE $LBC_NODEBUG_OPTIONS -- $ADDITIONAL_BUILD_OPTIONS ccache -s .job-macosx-desktop: stage: build tags: [ "macosx-xcode11" ] script: - *build_all_script artifacts: paths: - build/OUTPUT when: always expire_in: 1 week ################################################# # On each push ################################################# job-macosx-ninja: except: refs: - schedules variables: CMAKE_GENERATOR: Ninja extends: .job-macosx-desktop ################################################# # Nightly ################################################# job-macosx-makefile: only: variables: - $NIGHTLY_MASTER variables: CMAKE_GENERATOR: Unix Makefiles ADDITIONAL_BUILD_OPTIONS: -j$MAKEFILE_JOBS extends: .job-macosx-desktop job-macosx-ninja-novideo: only: variables: - $NIGHTLY_MASTER variables: CMAKE_OPTIONS: -DENABLE_VIDEO=NO CMAKE_GENERATOR: Ninja extends: .job-macosx-desktop #job-macosx-xcode: # extends: .job-macosx-desktop # variables: # XCODE_OPTIONS: -DLINPHONESDK_MACOS_BASE_URL=$MACOS_SNAPSHOTS_URL # CMAKE_GENERATOR: Xcode # ADDITIONAL_BUILD_OPTIONS: -IDEBuildOperationMaxNumberOfConcurrentCompileTasks=$MAX_NUMBER_TASK # only: # variables: # - $NIGHTLY_MASTER # - $DEPLOY_RUN_MACOSX # ################################################# # Package - Nightly ################################################# job-macosx-makefile-package: stage: package tags: [ "macosx-xcode11" ] dependencies: [] only: variables: - $NIGHTLY_MASTER - $DEPLOY_MACOSX variables: CMAKE_OPTIONS: -DENABLE_APP_PACKAGING=YES extends: job-macosx-makefile script: - *build_all_script - codesign --options runtime,library --verbose -s "$MACOS_SIGNING_IDENTITY" OUTPUT/Packages/Linphone*.dmg - ./../tools/app_notarization.sh artifacts: paths: - build/OUTPUT/* when: always expire_in: 1 week ################################################# # Deploy - Nightly ################################################# job-macosx-makefile-deploy: stage: deploy tags: [ "macosx-xcode11" ] dependencies: - job-macosx-makefile-package only: variables: - $NIGHTLY_MASTER - $DEPLOY_MACOSX script: - rsync -rlv --ignore-existing build/OUTPUT/Packages/Linphone*.dmg $DEPLOY_SERVER:$MACOSX_UPLOAD_DIRECTORY linphone-desktop-4.2.5/.gitlab-ci-files/job-windows-desktop.yml000066400000000000000000000054311376717241300244700ustar00rootroot00000000000000################################################# # BUILD ################################################# .build_all_windows_script: &build_all_windows_script | SET Qt5_DIR=C:\Qt\5.14.2\msvc2017\lib\cmake SET PATH=%PATH%;C:\Qt\5.14.2\msvc2017\bin IF EXIST build RMDIR /S /Q build mkdir build cd build mkdir OUTPUT C:\PROGRA~1\Python37\Scripts\cl -s cmake .. -G "Visual Studio 15 2017" -DLINPHONESDK_PLATFORM=Desktop -DCMAKE_BUILD_TYPE=%CI_BUILD_TYPE% %DEFAULT_WINDOWS_CMAKE_OPTIONS% %CMAKE_OPTIONS% cmake --build . --target install --config %CI_BUILD_TYPE% %LBC_NODEBUG_OPTIONS% -- /maxcpucount /nodeReuse:true /p:TrackFileAccess=false C:\PROGRA~1\Python37\Scripts\cl -s .job-windows-vs2017: extends: .job-prepare stage: build tags: [ "windows" ] variables: CMAKE_OPTIONS: -DENABLE_LIME_X3DH=NO -DENABLE_UNIT_TESTS=ON script: - *build_all_windows_script artifacts: paths: - build\OUTPUT when: always expire_in: 2 days job-windows-vs2017: except: refs: - schedules extends: .job-windows-vs2017 ################################################# # NIGHTLY ################################################# .job-windows-vs2017-scheduled: only: variables: - $NIGHTLY_MASTER - $NIGHTLY_RELEASE before_script: #cache disabled on scheduled builds since we dot not need the fastest build - set "CLCACHE_DISABLE=1" extends: .job-windows-vs2017 job-windows-vs2017-scheduled: extends: .job-windows-vs2017-scheduled job-windows-vs2017-novideo: extends: .job-windows-vs2017-scheduled variables: CMAKE_OPTIONS: -DENABLE_LIME_X3DH=NO -DENABLE_VIDEO=NO ################################################# # PACKAGE ################################################# #Remove . when packaging process is ready to use job-windows-vs2017-package: stage: package tags: [ "windows" ] dependencies: [] only: variables: - $NIGHTLY_MASTER - $DEPLOY_WINDOWS variables: CMAKE_OPTIONS: -DENABLE_APP_PACKAGING=YES -DLINPHONE_WINDOWS_SIGNING_DIR=$WINDOWS_SIGNING_DIRECTORY script: - *build_all_windows_script - C:\PROGRA~1\Python37\Scripts\cl -s - mkdir "%CI_PROJECT_DIR%/results" - cd OUTPUT - cd Packages - copy /B *.exe "%CI_PROJECT_DIR%/results" artifacts: paths: - results\* when: always expire_in: 1 weeks ################################################# # DEPLOY ################################################# job-windows-vs2017-win32-upload: stage: deploy tags: [ "windows"] only: variables: - $NIGHTLY_MASTER - $DEPLOY_WINDOWS dependencies: - job-windows-vs2017-package script: - scp "results/*.exe" "%DEPLOY_SERVER%:%WINDOWS_UPLOAD_DIRECTORY%" linphone-desktop-4.2.5/.gitlab-ci.yml000066400000000000000000000041641376717241300174610ustar00rootroot00000000000000################################################# # Base configuration ################################################# variables: GIT_SUBMODULE_STRATEGY: recursive MAKEFILE_JOBS: 5 CCACHE_SIZE: 2G #this option is used to speedup submodule building times, when we don't need to trace debug (like SDK where it is already tested in its project) LBC_NODEBUG_OPTIONS : --parallel $MAKEFILE_JOBS DEFAULT_LINUX_CMAKE_OPTIONS: -DCMAKE_BUILD_PARALLEL_LEVEL=$MAKEFILE_JOBS DEFAULT_MACOS_CMAKE_OPTIONS: -DCMAKE_BUILD_PARALLEL_LEVEL=$MAKEFILE_JOBS DEFAULT_WINDOWS_CMAKE_OPTIONS: -DCMAKE_BUILD_PARALLEL_LEVEL=$MAKEFILE_JOBS # DEFAULT_LINUX_CMAKE_OPTIONS: -DENABLE_NON_FREE_CODECS=YES -DENABLE_OPENH264=YES # DEFAULT_MACOS_CMAKE_OPTIONS: -DCMAKE_OSX_DEPLOYMENT_TARGET=10.11 -DENABLE_UPDATE_CHECK=YES # DEFAULT_WINDOWS_CMAKE_OPTIONS: -DENABLE_NON_FREE_CODECS=YES -DENABLE_OPENH264=YES -DENABLE_UPDATE_CHECK=YES #activated by default, if there is a problem, see the default #build options in CMakeBuilder #CMAKE_OPTIONS: -DENABLE_LIME_X3DH=YES ################################################# # Platforms to test ################################################# .job-prepare: variables: ALL_JOB_VARIABLE: "" include: - '.gitlab-ci-files/job-linux-prepare.yml' - '.gitlab-ci-files/job-linux-desktop.yml' #- '.gitlab-ci-files/job-linux-desktop-debian8.yml' #Removed as there is 5.10 and not at least 5.12 - '.gitlab-ci-files/job-linux-desktop-debian9.yml' ## - '.gitlab-ci-files/job-linux-desktop-debian10.yml' - '.gitlab-ci-files/job-linux-desktop-ubuntu-rolling.yml' - '.gitlab-ci-files/job-linux-desktop-archlinux-latest.yml' - '.gitlab-ci-files/job-linux-desktop-centos7.yml' - '.gitlab-ci-files/job-windows-desktop.yml' - '.gitlab-ci-files/job-macosx-desktop.yml' # - '.gitlab-ci-files/job-linux.yml' # - '.gitlab-ci-files/job-linux-archlinux.yml' # - '.gitlab-ci-files/job-linux-centos7.yml' # - '.gitlab-ci-files/job-linux-debian8.yml' # - '.gitlab-ci-files/job-linux-debian9.yml' # - '.gitlab-ci-files/job-macosx.yml' # - '.gitlab-ci-files/job-windows.yml' stages: - build - package - deploy linphone-desktop-4.2.5/.gitmodules000066400000000000000000000003161376717241300171750ustar00rootroot00000000000000[submodule "submodules/externals/minizip"] path = submodules/externals/minizip url = ../../public/external/minizip.git [submodule "linphone-sdk"] path = linphone-sdk url = ../../public/linphone-sdk.git linphone-desktop-4.2.5/.tx/000077500000000000000000000000001376717241300155315ustar00rootroot00000000000000linphone-desktop-4.2.5/.tx/config000066400000000000000000000003021376717241300167140ustar00rootroot00000000000000[main] host = https://www.transifex.com [linphone-desktop.ts] file_filter = linphone-app/assets/languages/.ts source_file = linphone-app/assets/languages/en.ts source_lang = en type = QT linphone-desktop-4.2.5/CHANGELOG.md000066400000000000000000000140111376717241300166260ustar00rootroot00000000000000# Changelog All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## 4.2.4 - 2020-11-?? ### Added - Play DTMF when receiving it and show the Dialpad on outgoing call to allow sending DTMF - Update settings view to not deactivate transport but allow not binding port - Show all call logs by clicking on `previously` bar ### Fixed - Displaying names in UTF8 - Keep unsend typed message in memory when changing of chat room - Log files have Qt logs - Add `SOCI Sqlite3` library in Appimage - Use the more generic `linphone` folder and not `Linphone` for installation - Simplify build process to use install keyword ## 4.2.3 - 2020-10-09 ### Added - Add support to tel and callto protocols - Allow Pulseaudio to switch devices automatically. For example, it will mute all applications that have music when receive a call from Linphone. ### Fixed - Contact name can contain special characters - Avoid to reduce window if it is currently maximized when clicking on contacts - Cleaner use of Windows registries ## 4.2.2 - 2020-07-30 ### Fixed - Crash on Opus ## 4.2.1 - 2020-07-03 ### Fixed - Crash on registration - Multiple popup were hidden : show them as a stack view ## 4.2.0 - 2020-06-26 ### Added - Added a `CLI` function in order to support `URI handlers` from browsers. Help is available with `linphone --cli-help`. (See also: https://wiki.linphone.org/xwiki/wiki/public/view/Linphone/URI%20Handlers%20%28Desktop%20only%29/). - Improved general audio/video quality thanks to better rate control algorithms in liblinphone and mediastreamer2. - More efficient echo cancellation. - `OpenH264` codec can be downloaded and used in the application from Cisco website. - `G729` codec can be used in the application. - Improved High DPI Displays support for 4K screens. - On multiscreens, when choosing full screen mode during a call, the call screen open in the current screen. The old behaviour kept the call screen in the primary screen. - Detect audio/video hardware changes while using settings. - Updatable audio/video devices while in call. - Added an option to automatically show Dialpad. - Dialpad supports A, B, C and D keys. - Dialpad supports keyboard when hovering on it. - DTMF sound played when sent. - Added an option to keep windows in background when a call is received. - Added an option to allow Linphone to be launched automatically with the system (autostart). - Added an option to play sound notification when an incoming chat message is received. - Added Call tools in Fullscreen mode (medias settings, security, mutable speaker). - Audio settings display the microphone being used and allow you to adjust capture and playback gains. - Conference participants are mutable by clicking on them. - Added the possibility to record calls automatically. - Moved logs folder without restart. - Added caller and callee information into file names of recordings. - Enhanced interface for switching between multiple SIP accounts: the timeline now shows activity for the currently selected SIP account only. - Timeline uses current proxy config info and show data only on selected profile. - Tooltips can be shown in multiple lines. - Display the name of the caller in incoming notifications. - Notifications are shown in all available screens. - Display unread message count in system tray (Linphone icon). - Display unread chat message count and missed calls in `Manage Accounts` dialog and in `Main Window`. - Added a media parameter dialog in the `Call View` to select devices and set volume. - Display a spinner when a message is being sent. - Disabled screensaver on fullscreen video call. - New logo, icons and installer assets. - New Linux deployment (Appimage). - Supports chinese, danish, french, english, german, hungarian, italian, japanese, lithuanian, portuguese, russian, spanish, swedish, turkish, ukrainian from community contributions. - Use Native BZip2 instead of Embedded Minizip to extract `OpenH264` codec. - App Nap avoiding for MacOs. - Simplified building process. ### Changed - Upgraded to use QT 5.12. - Depends on linphone-sdk project (numerous direct submodules removed). - License changed from GPLv2 to GPLv3. ### Fixed - Removed `:` separator from file names of recordings because it is not allowed on Windows. - Avoided mark `as read` on selected chat rooms if window is not active. - Search box in main page will not reset text when clicking on it. - More stable account authentifications. - Message status behaviour : Resuming status when changing logs, cursor shapes updates, bind the resend message action to error icon. - Apple permissions that could lead to muted microphone. - Incoming call notification window (sometimes not showing). ### Removed - `Prepare.py` configuration. - Remove useless splashscreen. - `Minizip` dependencies. - `Flatpak` support. ## 4.1.0 - 2017-07-19 ### Added - Add tooltips on `recording` and `screenshot` buttons in `Calls Window`. - Show notifications on `recording` and `screenshot`. - Show `XXX is typing...` in `Timeline` and `Chat View`. - Handle correctly `SIGINT`. - Handle clicks on SIP URI in chat messages. - Show video framerate in `Calls Stats`. - Add a `Logs` menu entry in `Settings Window`, it provides send, remove, activate buttons... - Supports EXIF orientation for file transfer images preview. - Echo canceller supports 48kHz. - Better GUI when a proxy config is modified in `Settings Window`. ### Fixed - Handle correctly ringer device changes in `Settings Window`. - In `Video Settings`, display FPS field only in `custom preset` mode. - Use now the directory containing user documents files for saved video/audio/screenshots. - Update `Chat View` correctly if it is used in many windows. - Update correctly selected language when app is restarted. - Avoid a deadlock on Mac OS when a call ends in fullscreen mode. - Application can be started from one binary only. - Single instance is now supported with flatpak. (It uses D-Bus.) linphone-desktop-4.2.5/CMakeLists.txt000066400000000000000000000222351376717241300175640ustar00rootroot00000000000000################################################################################ # # Copyright (c) 2010-2020 Belledonne Communications SARL. # # This file is part of linphone-desktop # (see https://www.linphone.org). # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # ################################################################################ cmake_minimum_required(VERSION 3.1) get_cmake_property(vars CACHE_VARIABLES) foreach(var ${vars}) get_property(currentHelpString CACHE "${var}" PROPERTY HELPSTRING) if("${currentHelpString}" MATCHES "No help, variable specified on the command line." OR "${currentHelpString}" STREQUAL "") #message("${var} = [${${var}}] -- ${currentHelpString}") # uncomment to see the variables being processed list(APPEND USER_ARGS "-D${var}=${${var}}") if( "${var}" STREQUAL "CMAKE_PREFIX_PATH") set(PREFIX_PATH ";${${var}}") endif() elseif("${var}" STREQUAL "CMAKE_GENERATOR_PLATFORM" AND NOT("${${var}}" STREQUAL "")) message(STATUS "User-Setting Platform to ${${var}}") endif() endforeach() if(ENABLE_BUILD_VERBOSE) message("User Args : ${USER_ARGS}") endif() if(NOT CMAKE_GENERATOR_PLATFORM AND WIN32) set(CMAKE_GENERATOR_PLATFORM "Win32") message(STATUS "Setting Platform to ${CMAKE_GENERATOR_PLATFORM}") endif() project(linphoneqt) include(GNUInstallDirs) include(CheckCXXCompilerFlag) # Prepare gobal CMAKE configuration specific to the current project set(SDK_BUILD_DIR "${CMAKE_BINARY_DIR}/WORK") # SDK build in WORK. Keep all in it. set(LINPHONE_OUTPUT_DIR "${CMAKE_BINARY_DIR}/linphone-sdk/desktop") set(APPLICATION_OUTPUT_DIR "${CMAKE_BINARY_DIR}/OUTPUT") set(CMAKE_PREFIX_PATH "${LINPHONE_OUTPUT_DIR};${APPLICATION_OUTPUT_DIR}${PREFIX_PATH}") string(REPLACE ";" "|" PREFIX_PATH "${CMAKE_PREFIX_PATH}") #set(PREFIX_PATH "${LINPHONE_OUTPUT_DIR}|${APPLICATION_OUTPUT_DIR}${PREFIX_PATH}") # Avoid cmake warning if CMP0071 is not set. if (POLICY CMP0071) cmake_policy(SET CMP0071 NEW) endif () #set_property(GLOBAL PROPERTY USE_FOLDERS ON) #------------------------------------------------------------------------------ if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) message(STATUS "Setting build type to 'RelWithDebInfo' as none was specified") set(CMAKE_BUILD_TYPE "RelWithDebInfo" CACHE STRING "Choose the type of build, options are: Debug Release RelWithDebInfo" FORCE) # Set the available build type values for cmake-gui set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release" "RelWithDebInfo") endif() # ------------------------------------------------------------------------------ #------------------------------------------------------------------------------- # SET OPTIONS #------------------------------------------------------------------------------- option(ENABLE_APP_PACKAGING "Enable packaging" NO) option(ENABLE_UPDATE_CHECK "Enable update check." YES) option(ENABLE_UNIT_TESTS "Enable unit test of SDK." NO ) option(ENABLE_TESTS "Build with testing binaries of SDK" NO ) option(ENABLE_TESTS_COMPONENTS "Build libbctoolbox-tester" NO ) option(ENABLE_TOOLS "Enable tools of SDK" NO) option(ENABLE_STRICT "Build with strict compilator flags e.g. -Wall -Werror" NO) option(ENABLE_FFMPEG "Build mediastreamer2 with ffmpeg video support." YES) option(ENABLE_BUILD_VERBOSE "Enable the build generation to be more verbose" NO) option(ENABLE_OPENH264 "Enable the use of OpenH264 codec" YES) option(ENABLE_NON_FREE_CODECS "Enable the use of non free codecs" YES) if(WIN32 OR APPLE) else() option(ENABLE_V4L "Ability to capture and display video using libv4l2 or libv4l." YES) endif() option(ENABLE_RELATIVE_PREFIX "Set Internal packages relative to the binary" YES) set(APP_OPTIONS "-DENABLE_UPDATE_CHECK=${ENABLE_UPDATE_CHECK}") list(APPEND APP_OPTIONS "-DENABLE_APP_PACKAGING=${ENABLE_APP_PACKAGING}") list(APPEND APP_OPTIONS "-DENABLE_UNIT_TESTS=${ENABLE_UNIT_TESTS}") list(APPEND APP_OPTIONS "-DENABLE_TESTS=${ENABLE_TESTS}") list(APPEND APP_OPTIONS "-DENABLE_TESTS_COMPONENTS=${ENABLE_TESTS_COMPONENTS}") list(APPEND APP_OPTIONS "-DENABLE_TOOLS=${ENABLE_TOOLS}") list(APPEND APP_OPTIONS "-DENABLE_STRICT=${ENABLE_STRICT}") list(APPEND APP_OPTIONS "-DENABLE_FFMPEG=${ENABLE_FFMPEG}") list(APPEND APP_OPTIONS "-DENABLE_BUILD_VERBOSE=${ENABLE_BUILD_VERBOSE}") list(APPEND APP_OPTIONS "-DENABLE_OPENH264=${ENABLE_OPENH264}") list(APPEND APP_OPTIONS "-DENABLE_NON_FREE_CODECS=${ENABLE_NON_FREE_CODECS}") if(ENABLE_V4L) list(APPEND APP_OPTIONS "-DENABLE_V4L=${ENABLE_V4L}") endif() list(APPEND APP_OPTIONS "-DENABLE_RELATIVE_PREFIX=${ENABLE_RELATIVE_PREFIX}") list(APPEND APP_OPTIONS "-DLINPHONE_OUTPUT_DIR=${LINPHONE_OUTPUT_DIR}") include(ExternalProject) set(PROJECT_BUILD_COMMAND "") if(CMAKE_BUILD_PARALLEL_LEVEL) list(APPEND APP_OPTIONS "-DCMAKE_BUILD_PARALLEL_LEVEL=${CMAKE_BUILD_PARALLEL_LEVEL}") if(${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.12.0") #CMAKE_BUILD_PARALLEL_LEVEL will not always work for External projects list(APPEND PROJECT_BUILD_COMMAND "--parallel" "${CMAKE_BUILD_PARALLEL_LEVEL}") endif() endif() if(CMAKE_VERBOSE_MAKEFILE) list(APPEND APP_OPTIONS "-DCMAKE_VERBOSE_MAKEFILE=${CMAKE_VERBOSE_MAKEFILE}") if(${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.14.0") list(APPEND PROJECT_BUILD_COMMAND "--verbose") endif() endif() if(UNIX AND NOT APPLE) set(CMAKE_INSTALL_RPATH "$ORIGIN:$ORIGIN/lib64:$ORIGIN/../lib64:$ORIGIN/lib:$ORIGIN/../lib:${LINPHONE_OUTPUT_DIR}/${CMAKE_INSTALL_LIBDIR}") list(APPEND APP_OPTIONS "-DCMAKE_INSTALL_RPATH=${CMAKE_INSTALL_RPATH}") endif() ExternalProject_Add(sdk PREFIX "${CMAKE_BINARY_DIR}/sdk" SOURCE_DIR "${CMAKE_SOURCE_DIR}/linphone-sdk" INSTALL_DIR "${LINPHONE_OUTPUT_DIR}" STAMP_DIR "${SDK_BUILD_DIR}/stamp" BINARY_DIR "${SDK_BUILD_DIR}" STEP_TARGETS build BUILD_COMMAND ${CMAKE_COMMAND} --build --config $ ${PROJECT_BUILD_COMMAND} INSTALL_COMMAND ${CMAKE_COMMAND} -E echo "Install step is already done at build time." LIST_SEPARATOR | # Use the alternate list separator CMAKE_ARGS ${APP_OPTIONS} ${USER_ARGS} -DCMAKE_INSTALL_PREFIX:PATH= -DCMAKE_PREFIX_PATH=${PREFIX_PATH} #BUILD_ALWAYS NO #${DO_BUILD} ) ExternalProject_Add_Step(sdk force_build COMMENT "Forcing build for 'desktop'" DEPENDEES configure DEPENDERS build ALWAYS 1 ) include(FindPkgConfig) set(APP_DEPENDS sdk) find_package(Qt5 5.12 COMPONENTS Core REQUIRED) if ( NOT Qt5_FOUND ) message(FATAL_ERROR "Minimum supported Qt5 version is 5.12!") endif() find_package(LinphoneCxx CONFIG QUIET) find_package(Linphone CONFIG QUIET) find_package(bctoolbox CONFIG QUIET) find_package(belcard CONFIG QUIET) find_package(Mediastreamer2 CONFIG QUIET) find_package(ortp CONFIG QUIET) if(NOT (LinphoneCxx_FOUND) OR NOT (Linphone_FOUND) OR NOT (bctoolbox_FOUND) OR NOT (belcard_FOUND) OR NOT (Mediastreamer2_FOUND) OR NOT (ortp_FOUND) OR FORCE_APP_EXTERNAL_PROJECTS) message("Projects are set as External projects. You can start building them by using for example : cmake --build . --target install") ExternalProject_Add(linphone-qt PREFIX "${CMAKE_BINARY_DIR}/linphone-app" SOURCE_DIR "${CMAKE_SOURCE_DIR}/linphone-app" INSTALL_DIR "${APPLICATION_OUTPUT_DIR}" BINARY_DIR "${CMAKE_BINARY_DIR}/linphone-app" DEPENDS ${APP_DEPENDS} BUILD_COMMAND ${CMAKE_COMMAND} --build --config $ ${PROJECT_BUILD_COMMAND} INSTALL_COMMAND ${CMAKE_COMMAND} -E echo "Install step will not be done by external project" LIST_SEPARATOR | # Use the alternate list separator CMAKE_ARGS ${APP_OPTIONS} ${USER_ARGS} -DCMAKE_INSTALL_PREFIX:PATH= -DCMAKE_PREFIX_PATH=${PREFIX_PATH} # ${APP_OPTIONS} BUILD_ALWAYS ON ) install(CODE "message(STATUS Running install)") set(AUTO_REGENERATION auto_regeneration) add_custom_target(${AUTO_REGENERATION} ALL COMMAND ${CMAKE_COMMAND} ${CMAKE_CURRENT_SOURCE_DIR} DEPENDS linphone-qt) else() message("Adding Linphone Desktop in an IDE-friendly state") set(CMAKE_INSTALL_PREFIX "${APPLICATION_OUTPUT_DIR}") add_subdirectory(${CMAKE_SOURCE_DIR}/linphone-app) add_dependencies(app-library ${APP_DEPENDS}) endif() ExternalProject_Add(linphone-qt-only PREFIX "${CMAKE_BINARY_DIR}/linphone-app" SOURCE_DIR "${CMAKE_SOURCE_DIR}/linphone-app" INSTALL_DIR "${APPLICATION_OUTPUT_DIR}" BINARY_DIR "${CMAKE_BINARY_DIR}/linphone-app" BUILD_COMMAND ${CMAKE_COMMAND} --build --config $ ${PROJECT_BUILD_COMMAND} # INSTALL_COMMAND ${CMAKE_COMMAND} -E echo "Install step is already done at build time." LIST_SEPARATOR | # Use the alternate list separator CMAKE_ARGS ${APP_OPTIONS} ${USER_ARGS} -DCMAKE_INSTALL_PREFIX:PATH= -DCMAKE_PREFIX_PATH=${PREFIX_PATH} EXCLUDE_FROM_ALL ON BUILD_ALWAYS ON ) linphone-desktop-4.2.5/LICENSE.txt000066400000000000000000001045161376717241300166520ustar00rootroot00000000000000 GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The GNU General Public License is a free, copyleft license for software and other kinds of works. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things. To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others. For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. Developers that use the GNU GPL protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it. For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions. Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users. Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free. The precise terms and conditions for copying, distribution and modification follow. TERMS AND CONDITIONS 0. Definitions. "This License" refers to version 3 of the GNU General Public License. "Copyright" also means copyright-like laws that apply to other kinds of works, such as semiconductor masks. "The Program" refers to any copyrightable work licensed under this License. Each licensee is addressed as "you". "Licensees" and "recipients" may be individuals or organizations. To "modify" a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a "modified version" of the earlier work or a work "based on" the earlier work. A "covered work" means either the unmodified Program or a work based on the Program. To "propagate" a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well. To "convey" a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying. An interactive user interface displays "Appropriate Legal Notices" to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion. 1. Source Code. The "source code" for a work means the preferred form of the work for making modifications to it. "Object code" means any non-source form of a work. A "Standard Interface" means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language. The "System Libraries" of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A "Major Component", in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it. The "Corresponding Source" for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work. The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source. The Corresponding Source for a work in source code form is that same work. 2. Basic Permissions. All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law. You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you. Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary. 3. Protecting Users' Legal Rights From Anti-Circumvention Law. No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures. When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures. 4. Conveying Verbatim Copies. You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program. You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee. 5. Conveying Modified Source Versions. You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions: a) The work must carry prominent notices stating that you modified it, and giving a relevant date. b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to "keep intact all notices". c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it. d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so. A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an "aggregate" if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate. 6. Conveying Non-Source Forms. You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways: a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange. b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge. c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b. d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements. e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d. A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work. A "User Product" is either (1) a "consumer product", which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, "normally used" refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product. "Installation Information" for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made. If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM). The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network. Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying. 7. Additional Terms. "Additional permissions" are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions. When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission. Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms: a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or d) Limiting the use for publicity purposes of names of licensors or authors of the material; or e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors. All other non-permissive additional terms are considered "further restrictions" within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying. If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms. Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way. 8. Termination. You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11). However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10. 9. Acceptance Not Required for Having Copies. You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so. 10. Automatic Licensing of Downstream Recipients. Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License. An "entity transaction" is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts. You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it. 11. Patents. A "contributor" is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's "contributor version". A contributor's "essential patent claims" are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, "control" includes the right to grant patent sublicenses in a manner consistent with the requirements of this License. Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version. In the following three paragraphs, a "patent license" is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To "grant" such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party. If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. "Knowingly relying" means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid. If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it. A patent license is "discriminatory" if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007. Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law. 12. No Surrender of Others' Freedom. If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program. 13. Use with the GNU Affero General Public License. Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such. 14. Revised Versions of this License. The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation. If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program. Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version. 15. Disclaimer of Warranty. THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. Limitation of Liability. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 17. Interpretation of Sections 15 and 16. If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . Also add information on how to contact you by electronic and paper mail. If the program does terminal interaction, make it output a short notice like this when it starts in an interactive mode: Copyright (C) This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, your program's commands might be different; for a GUI interface, you would use an "about box". You should also get your employer (if you work as a programmer) or school, if any, to sign a "copyright disclaimer" for the program, if necessary. For more information on this, and how to apply and follow the GNU GPL, see . The GNU General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. But first, please read . linphone-desktop-4.2.5/README.md000066400000000000000000000332731376717241300163070ustar00rootroot00000000000000[![pipeline status](https://gitlab.linphone.org/BC/public/linphone-desktop/badges/master/pipeline.svg)](https://gitlab.linphone.org/BC/public/linphone-desktop/commits/master) # Linphone Desktop Linphone is an open source softphone for voice and video over IP calling and instant messaging. It is fully SIP-based, for all calling, presence and IM features. General description is available from [linphone web site](https://www.linphone.org/technical-corner/linphone) ### License Copyright © Belledonne Communications Linphone is dual licensed, and is available either : - under a [GNU/GPLv3 license](https://www.gnu.org/licenses/gpl-3.0.en.html), for free (open source). Please make sure that you understand and agree with the terms of this license before using it (see LICENSE file for details). - under a proprietary license, for a fee, to be used in closed source applications. Contact [Belledonne Communications](https://www.linphone.org/contact) for any question about costs and services. ### Documentation - [Supported features and RFCs](https://www.linphone.org/technical-corner/linphone/features) - [Linphone public wiki](https://wiki.linphone.org/xwiki/wiki/public/view/Linphone/) ## Getting started Here are the general instructions to build linphone for desktop. The specific instructions for each build platform is described just below. You will need the tools : - `cmake` >= 3.6 : download it in https://cmake.org/download/ - `python` : https://www.python.org/downloads/release/python-381/ - `pip` : it is already embedded inside Python, so there should be nothing to do about it - `yasm` : https://yasm.tortall.net/Download.html - `nasm` : https://www.nasm.us/pub/nasm/releasebuilds/ - `doxygen` (required for the Cxx Wrapper) - `Perl` : (can be downloaded at http://strawberryperl.com/ for Windows. Set your Path to perl binaries) - `Pystache` : use 'pip install pystache --user' - `six` : use 'pip install six --user' - `git` For Desktop : you will need [Qt5](https://www.qt.io/download-thank-you) (_5.9 or newer_). `C++11` support is required! ### Set your environment 1. It's necessary to install the `pip` command and to execute: pip install pystache 2. You have to set the environment variable `Qt5_DIR` to point to the path containing the cmake folders of Qt5, and the `PATH` to the Qt5 `bin`. Example: Qt5_DIR="~/Qt/5.12.5/gcc_64/lib/cmake" PATH="~/Qt/5.12.5/gcc_64/bin/:$PATH" Note: If you have `qtchooser` set in your `PATH`, the best use is : eval "$(qtchooser -print-env)" export Qt5_DIR=${QTLIBDIR}/cmake/Qt5 export PATH=${QTTOOLDIR}:$PATH 3. For specific requirments, see platform instructions sections below. ### Resume of Building steps `git clone git@gitlab.linphone.org:BC/public/linphone-desktop.git --recursive` or `git clone https://gitlab.linphone.org/BC/public/linphone-desktop.git --recursive` `cd linphone-desktop` `mkdir build` `cd build` `cmake .. -DCMAKE_BUILD_PARALLEL_LEVEL=10 -DCMAKE_BUILD_TYPE=RelWithDebInfo` `cmake --build . --target install --parallel 10 --config RelWithDebInfo` `./OUTPUT/bin/linphone --verbose` or `./OUTPUT/Linphone.app/Contents/MacOS/linphone --verbose` ### Get sources 1. Clone repository: git clone git@gitlab.linphone.org:BC/public/linphone-desktop.git --recursive Or git clone https://gitlab.linphone.org/BC/public/linphone-desktop.git --recursive 2. Update submodules git submodule update --init --recursive ### Building : General Steps The build is done by building the SDK and the application. Their targets are `sdk` and `linphone-qt`. 1. Create your build folder at the root of the project : `mkdir build` Go to this new folder and begin the build process : `cd build` 2. Prepare your options : `cmake ..`. By default, it will try compile all needed dependencies. You can remove some by adding `-DENABLE_=NO` to the command. You can use `cmake-gui ..` if you want to have a better access to them. You can add `-DCMAKE_BUILD_PARALLEL_LEVEL=10` to do 10 parallel builds for speeding up the process. If it doesn't seem to work then it will be better to use CMake >= 3.12 Also, you can add `-DENABLE_BUILD_VERBOSE=ON` to get more feedback while generating the project. Note : For Makefile or Ninja, you have to add `-DCMAKE_BUILD_TYPE=` if you wish to build in a specific configuration (for example `RelWithDebInfo`). 3. Build and install the whole project : `cmake --build . --target ` (replace `` with the target name. You can use the switch `--parallel 10` to do 10 parallel builds with CMake >= 3.12. Note : For XCode or Visual Studio, you have to add `--config ` if you wish to build in a specific configuration (for example `RelWithDebInfo`). When all are over, the files will be in the OUTPUT folder in the build directory. When rebuilding, you have to use `cmake --build . --target install` (or `cmake --install .` if CMake>=3.15) to put the application in the correct configuration. 4. When doing some modifications in the SDK, you can rebuild only the sdk with the target `sdk` and the same for the application with `linphone-qt-only` 5. In order to get packages, you can use `cmake .. -DENABLE_APP_PACKAGING=YES`. The files will be in `OUTPUT/packages` folder. ### Update your project 1. Update your project with : git fetch git pull --rebase 2. Update submodules from your current branch git submodule update --init --recursive Then simply re-build using cmake. #### General Troubleshooting * The latest version of Doxygen may not work with the SDK. If you some build issues and have a specific version of Doxygen that is not in your PATH, you can use `-DLINPHONESDK_DOXYGEN_PROGRAM`. Eg on Mac : `-DLINPHONESDK_DOXYGEN_PROGRAM=/Applications/Doxygen.app/Contents/Resources/doxygen` * If the build of the SDK crash with something like "cmd.exe failed" and no more info, it can be a dependency that is not available. You have to check if all are in your PATH. Usually, if it is about VPX or Decaf, this could come from your Perl installation. * If the application doesn't start and create an empty file with a random name, it could be come from a bad configuration between your application and others submodules. Check your configurations and force them with `-DCMAKE_BUILD_TYPE=` or `--config `. ## Specific instructions for the Mac Os X platform To install the required dependencies on Mac OS X, you can use [Homebrew](https://brew.sh/). Before you install packages with Brew, you may have to change directories permissions (if you can't change permissions with sudo on a MacOS >= High Sierra, get a look at [this StackOverflow answer](https://stackoverflow.com/questions/16432071/how-to-fix-homebrew-permissions#46844441)). 1. Install Xcode from the Apple store. Run it at least once to allow it to install its tools. 2. Install homebrew by following the instructions here https://brew.sh/ 3. Install dependencies: brew install cmake qt git 4. First ensure you have installed pip. You can get it for python 2.7 [there](https://stackoverflow.com/questions/34886101/how-to-install-pip-to-python-2-7-10-on-mac#34886254). 5. Then, you can install a pip package with the following command: pip install [package] For instance, if you don't have pystache and the dot package (contained in graphviz), enter the following commands: pip install pystache pip install graphviz 6. Build as usual (General Steps) : - `cmake .. -DCMAKE_BUILD_PARALLEL_LEVEL=10 -DCMAKE_BUILD_TYPE=RelWithDebInfo` - `cmake --build . --target all --parallel 10 --config RelWithDebInfo` 7. The project folder will be in the build directory and binaries should be in the OUTPUT folder. 8. When updating the project, the next build steps are a bit different: - `cmake --build . --target all --parallel 10 --config RelWithDebInfo` - `cmake --install .` (CMake >= 3.15) OR - `cmake --build . --target install --parallel 10 --config RelWithDebInfo` ## Specific instructions for the Windows platform 1. Ensure that you have downloaded the `Qt msvc2015 version` or `Qt msvc2017 version` (32-bit). (64-bit version is not supported at this moment by Linphone Desktop.) - `MinGW` : [download](https://sourceforge.net/projects/mingw/) - Select all installer options except Ada and Fortran - Install it in the default location (C:/Mingw), this is important as there are hardlinks on it. - The gcc version should be 6.3.0. It wasn't tested for other versions. It seems that MinGW from osdn.net try to install gcc 9 that breaks the build. - `Yasm` - download yasm-1.3.0-win32.exe - copy it to a bin directory of your user directory - rename yasm-1.3.0-win32.exe as yasm.exe - `nasm` : [download](https://www.nasm.us/pub/nasm/releasebuilds/2.14.02/win64/) - `git` : [download](https://git-scm.com/download/win) Visual Studio must also be properly configured with addons. Under "Tools"->"Obtain tools and features", make sure that the following components are installed: - Tasks: Select Windows Universal Platform development, Desktop C++ Development, .NET Development - Under "Installation details". Go to "Desktop C++ Development" and add "SDK Windows 8.1 and SDK UCRT" - Individual component: Windows 8.1 SDK 2. Or open a Command line with Visual Studio `Developer Command Prompt for VS 2017` and call qtenv2.bat that is in your qt binaries eg: `C:\Qt\\msvc2017\bin\qtenv2.bat` 3. Install msys-coreutils : `mingw-get install msys-coreutils` 4. Build as usual with adding `-A Win32` to `cmake ..` (General Steps) : - `cmake .. -DCMAKE_BUILD_PARALLEL_LEVEL=10 -DCMAKE_BUILD_TYPE=RelWithDebInfo -A Win32` - `cmake --build . --target ALL_BUILD --parallel 10 --config RelWithDebInfo` 5. The project folder will be in the build directory and binaries should be in the OUTPUT folder. 6. When updating the project, the next build steps are a bit different: - `cmake --build . --target ALL_BUILD --parallel 10 --config RelWithDebInfo` - `cmake --install .` (CMake >= 3.15) OR - `cmake --build . --target install --parallel 10 --config RelWithDebInfo` ## Specific instructions for the Mac Os X platform 1. Build as usual (General Steps) : - `cmake .. -DCMAKE_BUILD_PARALLEL_LEVEL=10 -DCMAKE_BUILD_TYPE=RelWithDebInfo` - `cmake --build . --target all --parallel 10 --config RelWithDebInfo` 2. The project folder will be in the build directory and binaries should be in the OUTPUT folder. 3. When updating the project, the next build steps are a bit different: - `cmake --build . --target all --parallel 10 --config RelWithDebInfo` - `cmake --install .` (CMake >= 3.15) OR - `cmake --build . --target install --parallel 10 --config RelWithDebInfo` ## Installing Linux dependencies Dependencies from 4.1 version of Desktop (refer it only if you have issues): apt-get install libqt53dcore5:amd64 libqt53dextras5:amd64 libqt53dinput5:amd64 libqt53dlogic5:amd64 libqt53dquick5:amd64 libqt53dquickextras5:amd64 libqt53dquickinput5:amd64 libqt53dquickrender5:amd64 libqt53drender5:amd64 libqt5concurrent5:amd64 libqt5core5a:amd64 libqt5dbus5:amd64 libqt5designer5:amd64 libqt5designercomponents5:amd64 libqt5gui5:amd64 libqt5help5:amd64 libqt5multimedia5:amd64 libqt5multimedia5-plugins:amd64 libqt5multimediawidgets5:amd64 libqt5network5:amd64 libqt5opengl5:amd64 libqt5opengl5-dev:amd64 libqt5positioning5:amd64 libqt5printsupport5:amd64 libqt5qml5:amd64 libqt5quick5:amd64 libqt5quickcontrols2-5:amd64 libqt5quickparticles5:amd64 libqt5quicktemplates2-5:amd64 libqt5quicktest5:amd64 libqt5quickwidgets5:amd64 libqt5script5:amd64 libqt5scripttools5:amd64 libqt5sensors5:amd64 libqt5serialport5:amd64 libqt5sql5:amd64 libqt5sql5-sqlite:amd64 libqt5svg5:amd64 libqt5svg5-dev:amd64 libqt5test5:amd64 libqt5webchannel5:amd64 libqt5webengine-data libqt5webenginecore5:amd64 libqt5webenginewidgets5:amd64 libqt5webkit5:amd64 libqt5widgets5:amd64 libqt5x11extras5:amd64 libqt5xml5:amd64 libqt5xmlpatterns5:amd64 qt5-default:amd64 qt5-doc qt5-gtk-platformtheme:amd64 qt5-qmake:amd64 qt5-qmltooling-plugins:amd64 ## Contributing ### Code In order to submit a patch for inclusion in linphone's source code: 1. First make sure that your patch applies to the latest Git sources before submitting : patches made to old versions can't and won't be merged. 2. Fill out and send the contributor agreement for your patch to be included in the Git tree by following links [there](https://www.linphone.org/contact). The goal of this agreement is to grant us the peaceful exercise of our rights to the Linphone source code, without losing your rights over your contribution. 3. Then go to the [github repository](https://github.com/BelledonneCommunications/linphone-desktop/pulls) and make a Pull Requests based on your code. Please note that we don't offer free support and these contributions will be addressed on our free-time. ### Languages Linphone is getting a full internationalization support, using Transifex platform. If you want you can contribute at: https://www.transifex.com/belledonne-communications/linphone-desktop/languages/ ### Feedback or bug reporting Launch the application with `--verbose` parameter to get full logs and send it with your request. You can use the "Send logs" button in settings to upload log files and share it by email or with a post in the corresponding github project : - [Desktop Application](https://github.com/BelledonneCommunications/linphone-desktop/issues) - [Linphone SDK](https://github.com/BelledonneCommunications/linphone-sdk/issues) On some OS (like Fedora 22 and later), they disable Qt debug output by default. To get full output, you need to create `~/.config/QtProject/qtlogging.ini` and add : [Rules] *.debug=true qt.*.debug=false linphone-desktop-4.2.5/linphone-app/000077500000000000000000000000001376717241300174125ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/CMakeLists.txt000066400000000000000000000477751376717241300221760ustar00rootroot00000000000000################################################################################ # # Copyright (c) 2017-2020 Belledonne Communications SARL. # # This file is part of linphone-desktop # (see https://www.linphone.org). # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # ################################################################################ cmake_minimum_required(VERSION 3.1) find_package(bctoolbox CONFIG) set(FULL_VERSION ) bc_compute_full_version(FULL_VERSION) set(version_major ) set(version_minor ) set(version_patch ) set(identifiers ) set(metadata ) bc_parse_full_version("${FULL_VERSION}" version_major version_minor version_patch identifiers metadata) project(linphoneqt VERSION "${version_major}.${version_minor}.${version_patch}") if(ENABLE_BUILD_VERBOSE) #message("CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH}") message("Options : ${ENABLE_UPDATE_CHECK}, ${ENABLE_UNIT_TESTS}, ${ENABLE_TESTS}, ${ENABLE_TESTS_COMPONENTS}, ${ENABLE_TOOLS}, ${ENABLE_STRICT}, ${ENABLE_FFMPEG}, ${ENABLE_OPUS}") endif() include(GNUInstallDirs) include(CheckCXXCompilerFlag) set(TARGET_NAME linphone-qt) set(CMAKE_CXX_STANDARD 11) if(UNIX AND NOT APPLE) set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE) endif() list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/../cmake") list(APPEND CMAKE_MODULE_PATH "${LINPHONE_OUTPUT_DIR}/cmake") set(APP_LIBRARY app-library) include(application_info.cmake) if(WIN32) set(EXECUTABLE_OUTPUT_DIR "${CMAKE_CURRENT_BINARY_DIR}") set( CMAKE_RUNTIME_OUTPUT_DIRECTORY ${EXECUTABLE_OUTPUT_DIR} ) set( CMAKE_LIBRARY_OUTPUT_DIRECTORY ${EXECUTABLE_OUTPUT_DIR} ) set( CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${EXECUTABLE_OUTPUT_DIR} ) foreach( OUTPUTCONFIG ${CMAKE_CONFIGURATION_TYPES} )# Apply to all configurations string( TOUPPER ${OUTPUTCONFIG} OUTPUTCONFIG ) set( CMAKE_RUNTIME_OUTPUT_DIRECTORY_${OUTPUTCONFIG} ${EXECUTABLE_OUTPUT_DIR} ) set( CMAKE_LIBRARY_OUTPUT_DIRECTORY_${OUTPUTCONFIG} ${EXECUTABLE_OUTPUT_DIR} ) set( CMAKE_ARCHIVE_OUTPUT_DIRECTORY_${OUTPUTCONFIG} ${EXECUTABLE_OUTPUT_DIR} ) endforeach( OUTPUTCONFIG CMAKE_CONFIGURATION_TYPES ) endif() find_package(LinphoneCxx CONFIG) find_package(Linphone CONFIG) find_package(belcard CONFIG) find_package(Mediastreamer2 CONFIG) find_package(ortp CONFIG) if(ENABLE_BUILD_VERBOSE) message("INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX} FRAMEWORK_PATH=${CMAKE_FRAMEWORK_PATH}, PREFIX_PATH=${CMAKE_PREFIX_PATH}") message("LINPHONE : ${LINPHONE_INCLUDE_DIRS} => ${LINPHONE_LIBRARIES}") message("LINPHONECXX : ${LINPHONECXX_INCLUDE_DIRS} => ${LINPHONECXX_LIBRARIES}") endif() # Build configuration set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -DNDEBUG -DQT_NO_DEBUG") set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -DQT_QML_DEBUG -DQT_DECLARATIVE_DEBUG") set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DDEBUG -DQT_QML_DEBUG -DQT_DECLARATIVE_DEBUG" ) if( WIN32) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D_WINSOCKAPI_")#remove error from windows headers order endif() set(CMAKE_INCLUDE_CURRENT_DIR ON)#useful for config.h set(QT5_PACKAGES Core Gui Quick Widgets QuickControls2 Svg LinguistTools Concurrent Network) if (UNIX AND NOT APPLE) list(APPEND QT5_PACKAGES DBus) endif () set(QT5_PACKAGES_OPTIONAL TextToSpeech) set(CMAKE_AUTOMOC ON) find_package(Qt5 COMPONENTS ${QT5_PACKAGES} REQUIRED) find_package(Qt5 COMPONENTS ${QT5_PACKAGES_OPTIONAL} QUIET) bc_git_version(${TARGET_NAME} ${PROJECT_VERSION}) #------------------------------------------------- set(ASSETS_DIR "assets") set(SOURCES src/app/App.cpp src/app/AppController.cpp src/app/cli/Cli.cpp src/app/logger/Logger.cpp src/app/paths/Paths.cpp src/app/providers/AvatarProvider.cpp src/app/providers/ImageProvider.cpp src/app/providers/ExternalImageProvider.cpp src/app/providers/ThumbnailProvider.cpp src/app/translator/DefaultTranslator.cpp src/components/assistant/AssistantModel.cpp src/components/authentication/AuthenticationNotifier.cpp src/components/call/CallModel.cpp src/components/calls/CallsListModel.cpp src/components/calls/CallsListProxyModel.cpp src/components/camera/Camera.cpp src/components/camera/CameraPreview.cpp src/components/camera/MSFunctions.cpp src/components/chat/ChatModel.cpp src/components/chat/ChatProxyModel.cpp src/components/codecs/AbstractCodecsModel.cpp src/components/codecs/AudioCodecsModel.cpp src/components/codecs/VideoCodecsModel.cpp src/components/conference/ConferenceAddModel.cpp src/components/conference/ConferenceHelperModel.cpp src/components/conference/ConferenceModel.cpp src/components/contact/ContactModel.cpp src/components/contact/VcardModel.cpp src/components/contacts/ContactsListModel.cpp src/components/contacts/ContactsListProxyModel.cpp src/components/core/CoreHandlers.cpp src/components/core/CoreManager.cpp src/components/core/event-count-notifier/AbstractEventCountNotifier.cpp src/components/file/FileDownloader.cpp src/components/file/FileExtractor.cpp src/components/history/HistoryModel.cpp src/components/history/HistoryProxyModel.cpp src/components/notifier/Notifier.cpp src/components/other/clipboard/Clipboard.cpp src/components/other/colors/Colors.cpp src/components/other/text-to-speech/TextToSpeech.cpp src/components/other/units/Units.cpp src/components/presence/OwnPresenceModel.cpp src/components/presence/Presence.cpp src/components/settings/AccountSettingsModel.cpp src/components/settings/SettingsModel.cpp src/components/sip-addresses/SipAddressesModel.cpp src/components/sip-addresses/SipAddressesProxyModel.cpp src/components/sip-addresses/SipAddressObserver.cpp src/components/sound-player/SoundPlayer.cpp src/components/telephone-numbers/TelephoneNumbersModel.cpp src/components/timeline/TimelineModel.cpp src/components/url-handlers/UrlHandlers.cpp src/utils/LinphoneUtils.cpp src/utils/MediastreamerUtils.cpp src/utils/QExifImageHeader.cpp src/utils/Utils.cpp ) set(HEADERS src/app/App.hpp src/app/AppController.hpp src/app/cli/Cli.hpp src/app/logger/Logger.hpp src/app/paths/Paths.hpp src/app/providers/AvatarProvider.hpp src/app/providers/ImageProvider.hpp src/app/providers/ExternalImageProvider.hpp src/app/providers/ThumbnailProvider.hpp src/app/single-application/SingleApplication.hpp src/app/translator/DefaultTranslator.hpp src/components/assistant/AssistantModel.hpp src/components/authentication/AuthenticationNotifier.hpp src/components/call/CallModel.hpp src/components/calls/CallsListModel.hpp src/components/calls/CallsListProxyModel.hpp src/components/camera/Camera.hpp src/components/camera/CameraPreview.hpp src/components/camera/MSFunctions.hpp src/components/chat/ChatModel.hpp src/components/chat/ChatProxyModel.hpp src/components/codecs/AbstractCodecsModel.hpp src/components/codecs/AudioCodecsModel.hpp src/components/codecs/VideoCodecsModel.hpp src/components/Components.hpp src/components/conference/ConferenceAddModel.hpp src/components/conference/ConferenceHelperModel.hpp src/components/conference/ConferenceModel.hpp src/components/contact/ContactModel.hpp src/components/contact/VcardModel.hpp src/components/contacts/ContactsListModel.hpp src/components/contacts/ContactsListProxyModel.hpp src/components/core/CoreHandlers.hpp src/components/core/CoreManager.hpp src/components/core/event-count-notifier/AbstractEventCountNotifier.hpp src/components/file/FileDownloader.hpp src/components/file/FileExtractor.hpp src/components/history/HistoryModel.hpp src/components/history/HistoryProxyModel.hpp src/components/notifier/Notifier.hpp src/components/other/clipboard/Clipboard.hpp src/components/other/colors/Colors.hpp src/components/other/desktop-tools/DesktopTools.hpp src/components/other/text-to-speech/TextToSpeech.hpp src/components/other/units/Units.hpp src/components/presence/OwnPresenceModel.hpp src/components/presence/Presence.hpp src/components/settings/AccountSettingsModel.hpp src/components/settings/SettingsModel.hpp src/components/sip-addresses/SipAddressesModel.hpp src/components/sip-addresses/SipAddressesProxyModel.hpp src/components/sip-addresses/SipAddressObserver.hpp src/components/sound-player/SoundPlayer.hpp src/components/telephone-numbers/TelephoneNumbersModel.hpp src/components/timeline/TimelineModel.hpp src/components/url-handlers/UrlHandlers.hpp src/utils/LinphoneUtils.hpp src/utils/MediastreamerUtils.hpp src/utils/QExifImageHeader.hpp src/utils/Utils.hpp ) set(MAIN_FILE src/app/main.cpp) if (APPLE) list(APPEND SOURCES src/app/single-application/SingleApplication.cpp src/components/core/event-count-notifier/EventCountNotifierMacOs.m src/components/other/desktop-tools/DesktopToolsMacOs.cpp src/components/other/desktop-tools/DesktopToolsMacOs.mm src/components/other/desktop-tools/screen-saver/ScreenSaverMacOs.m src/components/other/desktop-tools/state-process/StateProcessMacOs.mm ) list(APPEND HEADERS src/app/single-application/SingleApplicationPrivate.hpp src/components/core/event-count-notifier/EventCountNotifierMacOs.hpp src/components/other/desktop-tools/DesktopToolsMacOs.hpp ) elseif (WIN32) list(APPEND SOURCES src/app/single-application/SingleApplication.cpp src/components/core/event-count-notifier/EventCountNotifierSystemTrayIcon.cpp src/components/other/desktop-tools/DesktopToolsWindows.cpp ) list(APPEND HEADERS src/app/single-application/SingleApplicationPrivate.hpp src/components/core/event-count-notifier/EventCountNotifierSystemTrayIcon.hpp src/components/other/desktop-tools/DesktopToolsWindows.hpp ) else () list(APPEND SOURCES src/app/single-application/SingleApplicationDBus.cpp src/components/core/event-count-notifier/EventCountNotifierSystemTrayIcon.cpp src/components/other/desktop-tools/DesktopToolsLinux.cpp src/components/other/desktop-tools/screen-saver/ScreenSaverDBus.cpp src/components/other/desktop-tools/screen-saver/ScreenSaverXdg.cpp ) list(APPEND HEADERS src/app/single-application/SingleApplicationDBusPrivate.hpp src/components/core/event-count-notifier/EventCountNotifierSystemTrayIcon.hpp src/components/other/desktop-tools/DesktopToolsLinux.hpp src/components/other/desktop-tools/screen-saver/ScreenSaverDBus.hpp src/components/other/desktop-tools/screen-saver/ScreenSaverXdg.hpp ) endif () set(QRC_RESOURCES resources.qrc) #qt5_add_big_resources(QRC_BIG_RESOURCES resources.qrc) #Use this macro if resources size is too high set(LANGUAGES_DIRECTORY "${ASSETS_DIR}/languages") set(I18N_FILENAME i18n.qrc) set(LANGUAGES da de en es fr_FR hu it ja lt pt_BR ru sv tr uk zh_CN) # ------------------------------------------------------------------------------ function (PREPEND list prefix) set(new_list "") foreach (elem ${${list}}) list(APPEND new_list "${prefix}${elem}") endforeach () set(${list} ${new_list} PARENT_SCOPE) endfunction () # Force absolute paths. PREPEND(SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/") PREPEND(HEADERS "${CMAKE_CURRENT_SOURCE_DIR}/") # ------------------------------------------------------------------------------ # Compute QML files list. # ------------------------------------------------------------------------------ set(QML_SOURCES) file(STRINGS ${QRC_RESOURCES} QRC_RESOURCES_CONTENT) foreach (line ${QRC_RESOURCES_CONTENT}) set(result) string(REGEX REPLACE "^[ \t]*<[ \t]*file[ \t]*>[ \t]*(.+\\.[a-z]+)[ \t]*<[ \t]*/[ \t]*file[ \t]*>[ \t]*$" "\\1" result "${line}" ) string(REGEX MATCH "\\.[a-z]+$" is_ui ${result}) if (NOT ${is_ui} STREQUAL "") list(APPEND QML_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/${result}") endif () endforeach () # ------------------------------------------------------------------------------ # Init git hooks. # ------------------------------------------------------------------------------ if (NOT WIN32) add_custom_target( check_qml DEPENDS ${QML_SOURCES} COMMAND "${CMAKE_CURRENT_SOURCE_DIR}/../tools/check_qml_syntax" ) endif() execute_process(COMMAND ${CMAKE_COMMAND} -E copy "${CMAKE_CURRENT_SOURCE_DIR}/../tools/private/pre-commit" "${CMAKE_CURRENT_SOURCE_DIR}/../.git/hooks/pre-commit" ) set(_QML_IMPORT_PATHS "") list(APPEND _QML_IMPORT_PATHS "${CMAKE_CURRENT_SOURCE_DIR}/ui/modules") list(APPEND _QML_IMPORT_PATHS "${CMAKE_CURRENT_SOURCE_DIR}/ui/dev-modules") list(APPEND _QML_IMPORT_PATHS "${CMAKE_CURRENT_SOURCE_DIR}/ui/scripts") list(APPEND _QML_IMPORT_PATHS "${CMAKE_CURRENT_SOURCE_DIR}/ui/views") set(QML_IMPORT_PATH ${_QML_IMPORT_PATHS} CACHE STRING "Path used to locate CMake modules by Qt Creator" FORCE) set(QML2_IMPORT_PATH ${_QML_IMPORT_PATHS} CACHE STRING "Path used to locate CMake modules by Qt Creator" FORCE) set(QML_SOURCES_PATHS "${CMAKE_CURRENT_SOURCE_DIR}/ui/") set(QML_MODULES_PATHS ${QML_SOURCES_PATHS}) if(ENABLE_BUILD_VERBOSE)#useful to copy these Paths to QML previewers message("QML_IMPORT_PATH=${QML_IMPORT_PATH}" ) message("Qt5 Paths : Qt5_DIR=$ENV{Qt5_DIR}, PATH=$ENV{PATH}") endif() if(APPLE) if(MS2_PLUGINS_LOCATION) set(MSPLUGINS_DIR ${MS2_PLUGINS_LOCATION}) else() set(MSPLUGINS_DIR "Frameworks/mediastreamer2.framework/Versions/A/Libraries") endif() else() set(MSPLUGINS_DIR "plugins/mediastreamer") endif() configure_file("${CMAKE_CURRENT_SOURCE_DIR}/src/config.h.cmake" "${CMAKE_CURRENT_BINARY_DIR}/config.h") # ------------------------------------------------------------------------------ # Build. # ------------------------------------------------------------------------------ include_directories(src/) if (CMAKE_INSTALL_RPATH) #Retrieve lib path from a know QT executable get_target_property(LUPDATE_PATH Qt5::lupdate LOCATION) get_filename_component(LUPDATE_PATH "${LUPDATE_PATH}" DIRECTORY) get_filename_component(QT_PATH "${LUPDATE_PATH}/lib" ABSOLUTE) list(APPEND CMAKE_INSTALL_RPATH "${QT_PATH}") endif () # Add languages support. add_subdirectory("${LANGUAGES_DIRECTORY}" "assets/languages") list(APPEND SOURCES "${CMAKE_CURRENT_BINARY_DIR}/${LANGUAGES_DIRECTORY}/${I18N_FILENAME}") get_directory_property(TS_FILES DIRECTORY "${LANGUAGES_DIRECTORY}" DEFINITION TS_FILES) list(APPEND SOURCES ${TS_FILES}) # set application details if(WIN32) string(TIMESTAMP CURRENT_YEAR "%Y") set(COPYRIGTH_RANGE_DATE "2010-${CURRENT_YEAR}") configure_file("${CMAKE_CURRENT_SOURCE_DIR}/cmake_builder/linphone_package/windows/appDetailsWindows.rc.in" "${CMAKE_CURRENT_BINARY_DIR}/appDetailsWindows.rc") set(RC_FILE ${CMAKE_CURRENT_BINARY_DIR}/appDetailsWindows.rc) endif() add_library(${APP_LIBRARY} OBJECT ${SOURCES} ${HEADERS} ${QML_SOURCES} ${QRC_RESOURCES}) #add_library(${APP_LIBRARY} OBJECT ${SOURCES} ${HEADERS} ${QML_SOURCES}) if (WIN32) add_executable(${TARGET_NAME} WIN32 $ ${MAIN_FILE} ${QRC_BIG_RESOURCES} ${RC_FILE}) install(TARGETS linphone-qt RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}") if(MSVC AND (CMAKE_BUILD_TYPE STREQUAL "Debug" OR CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo")) install(FILES "$" DESTINATION ${CMAKE_INSTALL_BINDIR}) endif() elseif (APPLE) add_executable(${TARGET_NAME} $ ${MAIN_FILE} ${QRC_BIG_RESOURCES}) install(TARGETS linphone-qt RUNTIME DESTINATION "${APPLICATION_NAME}.app/Contents/MacOS") # using ${TARGET_NAME} lead to cmake error on target name. Use directly linphone-qt. else () add_executable(${TARGET_NAME} $ ${MAIN_FILE} ${QRC_BIG_RESOURCES}) install(TARGETS linphone-qt RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}") endif () set_source_files_properties( ${APP_LIBRARY} PROPERTIES EXTERNAL_OBJECT true GENERATED true ) set_property(TARGET ${APP_LIBRARY} PROPERTY POSITION_INDEPENDENT_CODE ON) #Need by Qt #Turn on automatic resources compilation by cmake #Instead of excplicitely calling qt5_add_resources set_property(TARGET ${APP_LIBRARY} PROPERTY AUTORCC ON) set_target_properties(${TARGET_NAME} PROPERTIES OUTPUT_NAME "${EXECUTABLE_NAME}") if(MSVC) set_target_properties(${TARGET_NAME} PROPERTIES PDB_NAME "${EXECUTABLE_NAME}_app") endif() #ExternalProject_Get_Property(project_a install_dir) #include_directories(${install_dir}/include) #add_dependencies(project_b_exe project_a) #target_link_libraries(project_b_exe ${install_dir}/lib/alib.lib) set(INCLUDED_DIRECTORIES "${LINPHONECXX_INCLUDE_DIRS}" ) set(LIBRARIES_LIST ${BCTOOLBOX_CORE_LIBRARIES} ${BELCARD_LIBRARIES} ${LINPHONE_LIBRARIES} ${LINPHONECXX_LIBRARIES} ${MEDIASTREAMER2_LIBRARIES} ${ORTP_LIBRARIES} ${OPUS_LIBRARIES}) if(WIN32) set(LIBRARIES) foreach(LIBRARY ${LIBRARIES_LIST})# Search for lib full path find_library(FIND_LIBRARY_ITEM_${LIBRARY} NAMES ${LIBRARY} lib${LIBRARY} REQUIRED)#find_library need a specific variable name each time if(FIND_LIBRARY_ITEM_${LIBRARY}) list(APPEND LIBRARIES ${FIND_LIBRARY_ITEM_${LIBRARY}}) else() message(SEND_ERROR "${LIBRARY} not found!") endif() endforeach() else() set(LIBRARIES ${LIBRARIES_LIST}) endif() if(ENABLE_BUILD_VERBOSE) message("LIBRARIES : ${LIBRARIES}") endif() foreach (package ${QT5_PACKAGES}) list(APPEND INCLUDED_DIRECTORIES "${Qt5${package}_INCLUDE_DIRS}") # `qt5_create_translation` is provided from `LinguistTools` package. # But the `Qt5::LinguistTools` lib does not exist. Remove it. if (NOT (${package} STREQUAL LinguistTools)) list(APPEND LIBRARIES ${Qt5${package}_LIBRARIES}) endif () endforeach () foreach (package ${QT5_PACKAGES_OPTIONAL}) if ("${Qt5${package}_FOUND}") message("Optional package ${package} found.") list(APPEND INCLUDED_DIRECTORIES "${Qt5${package}_INCLUDE_DIRS}") list(APPEND LIBRARIES ${Qt5${package}_LIBRARIES}) string(TOUPPER "${package}" INCLUDE_NAME) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D${INCLUDE_NAME}_ENABLED") else () message("Optional package ${package} not found.") endif () endforeach () if (APPLE) list(APPEND LIBRARIES "-framework Cocoa -framework IOKit -framework AVFoundation") # -framework linphone") #This doesn't work yet endif () target_include_directories(${APP_LIBRARY} SYSTEM PRIVATE ${INCLUDED_DIRECTORIES}) target_include_directories(${TARGET_NAME} SYSTEM PRIVATE ${INCLUDED_DIRECTORIES}) target_link_libraries(${TARGET_NAME} ${LIBRARIES}) if(WIN32) target_link_libraries(${TARGET_NAME} wsock32 ws2_32) endif() add_dependencies(${APP_LIBRARY} update_translations ${TARGET_NAME}-git-version) add_dependencies(${TARGET_NAME} ${APP_LIBRARY}) # ------------------------------------------------------------------------------ # CPack settings & RPM. # ------------------------------------------------------------------------------ set(TOOLS_DIR "${CMAKE_BINARY_DIR}/programs") set(LINPHONE_BUILDER_SIGNING_IDENTITY ${LINPHONE_BUILDER_SIGNING_IDENTITY}) add_subdirectory(build) add_subdirectory(cmake_builder/linphone_package) # ------------------------------------------------------------------------------ # To start better integration into IDE. # ------------------------------------------------------------------------------ source_group( "Qml" REGULAR_EXPRESSION ".+\.qml$" ) source_group( "Js" REGULAR_EXPRESSION ".+\.js$" ) source_group( "Svg" REGULAR_EXPRESSION ".+\.svg$" ) source_group( "Lang" REGULAR_EXPRESSION ".+\.ts$" ) source_group( "Rc" REGULAR_EXPRESSION ".+\.rc$" ) linphone-desktop-4.2.5/linphone-app/application_info.cmake000066400000000000000000000004201376717241300237260ustar00rootroot00000000000000set(APPLICATION_DESCRIPTION "A libre SIP client") set(APPLICATION_ID "com.belledonnecommunications.linphone") set(APPLICATION_NAME Linphone) set(APPLICATION_URL "https://www.linphone.org") set(APPLICATION_VENDOR "Belledonne Communications") set(EXECUTABLE_NAME linphone) linphone-desktop-4.2.5/linphone-app/assets/000077500000000000000000000000001376717241300207145ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/assets/app-icon.rc000066400000000000000000000000671376717241300227530ustar00rootroot00000000000000A ICON MOVEABLE PURE LOADONCALL DISCARDABLE "icon.ico" linphone-desktop-4.2.5/linphone-app/assets/assistant/000077500000000000000000000000001376717241300227255ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/assets/assistant/create-app-sip-account.rc000066400000000000000000000045001376717241300275160ustar00rootroot00000000000000
1 0 1 sip:voip-metrics@sip.linphone.org;transport=tls 1 180 600 sip:?@sip.linphone.org <sip:sip.linphone.org;transport=tls> 1 nat_policy_default_values sip.linphone.org message-expires=604800
stun.linphone.org stun,ice
https://www.linphone.org:444/lft.php
sips:rls@sip.linphone.org
sip.linphone.org SHA-256 -1 1 -1 64 1 ^[a-z0-9+_.\-]*$ https://subscribe.linphone.org:444/wizard.php
linphone-desktop-4.2.5/linphone-app/assets/assistant/use-app-sip-account.rc000066400000000000000000000045001376717241300270470ustar00rootroot00000000000000
1 0 1 sip:voip-metrics@sip.linphone.org;transport=tls 1 180 600 sip:?@sip.linphone.org <sip:sip.linphone.org;transport=tls> 1 nat_policy_default_values sip.linphone.org message-expires=604800
stun.linphone.org stun,ice
https://www.linphone.org:444/lft.php
sips:rls@sip.linphone.org
sip.linphone.org SHA-256 -1 1 -1 64 1 ^[a-z0-9+_.\-]*$ https://subscribe.linphone.org:444/wizard.php
linphone-desktop-4.2.5/linphone-app/assets/assistant/use-other-sip-account.rc000066400000000000000000000040071376717241300274120ustar00rootroot00000000000000
0 0 0 0 0 3600 1
MD5 -1 0 -1 128 1 ^[a-zA-Z0-9+_.\-]*$
linphone-desktop-4.2.5/linphone-app/assets/fonts/000077500000000000000000000000001376717241300220455ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/assets/fonts/NotoSans-hinted/000077500000000000000000000000001376717241300250625ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/assets/fonts/NotoSans-hinted/LICENSE_OFL.txt000066400000000000000000000103151376717241300274050ustar00rootroot00000000000000This Font Software is licensed under the SIL Open Font License, Version 1.1. This license is copied below, and is also available with a FAQ at: http://scripts.sil.org/OFL ----------------------------------------------------------- SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 ----------------------------------------------------------- PREAMBLE The goals of the Open Font License (OFL) are to stimulate worldwide development of collaborative font projects, to support the font creation efforts of academic and linguistic communities, and to provide a free and open framework in which fonts may be shared and improved in partnership with others. The OFL allows the licensed fonts to be used, studied, modified and redistributed freely as long as they are not sold by themselves. The fonts, including any derivative works, can be bundled, embedded, redistributed and/or sold with any software provided that any reserved names are not used by derivative works. The fonts and derivatives, however, cannot be released under any other type of license. The requirement for fonts to remain under this license does not apply to any document created using the fonts or their derivatives. DEFINITIONS "Font Software" refers to the set of files released by the Copyright Holder(s) under this license and clearly marked as such. This may include source files, build scripts and documentation. "Reserved Font Name" refers to any names specified as such after the copyright statement(s). "Original Version" refers to the collection of Font Software components as distributed by the Copyright Holder(s). "Modified Version" refers to any derivative made by adding to, deleting, or substituting -- in part or in whole -- any of the components of the Original Version, by changing formats or by porting the Font Software to a new environment. "Author" refers to any designer, engineer, programmer, technical writer or other person who contributed to the Font Software. PERMISSION & CONDITIONS Permission is hereby granted, free of charge, to any person obtaining a copy of the Font Software, to use, study, copy, merge, embed, modify, redistribute, and sell modified and unmodified copies of the Font Software, subject to the following conditions: 1) Neither the Font Software nor any of its individual components, in Original or Modified Versions, may be sold by itself. 2) Original or Modified Versions of the Font Software may be bundled, redistributed and/or sold with any software, provided that each copy contains the above copyright notice and this license. These can be included either as stand-alone text files, human-readable headers or in the appropriate machine-readable metadata fields within text or binary files as long as those fields can be easily viewed by the user. 3) No Modified Version of the Font Software may use the Reserved Font Name(s) unless explicit written permission is granted by the corresponding Copyright Holder. This restriction only applies to the primary font name as presented to the users. 4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font Software shall not be used to promote, endorse or advertise any Modified Version, except to acknowledge the contribution(s) of the Copyright Holder(s) and the Author(s) or with their explicit written permission. 5) The Font Software, modified or unmodified, in part or in whole, must be distributed entirely under this license, and must not be distributed under any other license. The requirement for fonts to remain under this license does not apply to any document created using the Font Software. TERMINATION This license becomes null and void if any of the above conditions are not met. DISCLAIMER THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE. linphone-desktop-4.2.5/linphone-app/assets/fonts/NotoSans-hinted/NotoSans-Bold.ttf000066400000000000000000015707741376717241300302500ustar00rootroot00000000000000 GDEF,GPOSXyGSUBD7jOS/2m ? @ A B F G G H H K S U U V V W \ ` ` c c f s t t u    $,44BBJS ;w-# ((    # % ) + , - . / 0 1 7  =  &E ( )\ , -^ / 1` 3 9c < <j I Ik N Nl U \m ` `u f mv o s~ u w y    = m q v z ~ ST  %&VV   , 2 5 8 9 : < > A J N T V  1f : ; > H K M O b f ,         ! ' ( ) X k m o p q r u v w y z | } ~   4nDFLTcyrlgreklatnkernmarkmkmk. oƖ2҄F׀ݾ V   |ff h 4Ff rt*0f 4 Bffff ^ Xf h h h ^ h h r r rF"` | h F  F4 " h" `" X  $ r   *0`F"\\br6vzv""FFFFFF""""````````""""4FF``fffffffffffp.^ ^^^l.....<FdZ $%&'()*./2345679:;<=>FYZ\^cm} #%'56789:<>BDFUZ[\^_`aceghklnopqrstuwx}    ?@DGISTVWXY`dfpuxy{}~   !#)+-/13579;=?EGIKMOPQRST`>?@ABCDEFGHIJKLM !"#         79:<#%'579OQS`. "$@`B D         m        -ZM(-279:<#%'579OQS`-d79:<#%'579OQS` ;-nPP-2"PF m]elrlmnopq]  l m n o p q        m]lmnopqru ?^achopqsw @r]^aehl lmnopqm]x|}>?@ABCDElmnopqz{|}~    x}>?z{ x} >?z{3x} >?@ABCDEz{|}~  V`9 VW^df"paprtp;ops a VWZ& 2 `df  * 2 `df  Qegodf[a*  `df  + 2 Q`defgo  [a[an_aZ Vdf  +  V`dfn-2-<;,;2,;2  0  "" " prtru cscopstp                                      <<<<              )ZZ                9>BFUUY^`aehllnnpqssuxz{}}     @@ CE GJNNPTVZ\\^^apu|/7:FHTXZ\^`dem{}$)ACCET`a>MZ[j{ $6>RUV`b $glmx      ! !<;<$$&&+''((..C//*2233U44774889:';;C<<===DDIIPKKPQUU:WW0YZ [[D\\ mmN}}M+U ++++QCD***Q**      :::##4$$0%%4&&0''4((0))++--//113355'66 7788 99::=<<=>>=BBCCDDFFUU YY ZZ[[\\]] ^^ ``Waa eeff ggVhh llnnTppWqqssVuuvv wwxxzz{{}}OOX &%1&32%2 S1%&& B$$R$R%' ' '  ;!<  !  <NM  @@CCDDEEGG)HH"II(JJ NNPP QQ8RRKSS$TT1VV3WWJXX3YYJZZI\\I^^2aabb ccddee8ffgg8hijj kkll mmnn oo8pp1uuvvwwKxx$yySzz{{>||H7/27/>1%GFGF7/EE3B3B  2    %>H7//6.6.6.6..          !!##))++--//11335577)88"99)::";;)<<"==)>>"??)@@"AACCEE(FF GG(HH II(JJ KK(LL MM(NN OOPP QQRR SSTT ``4aa0>?@EFM Z[jklq ry z{   T !"#$$P#L@?@?99 -  , 5 A A A : : ?,;,$$ &&**224477288 9:"<<===@@?DDEEFHIIJJ*KKNOPQRRSSTTUUVV9WW(XXY\]]5``?mmL}}K Q    ****    9  9##2$$(%%2&&(''2((()) **++ ,,-- ..// 0011 2233 4455"66778899::=;;5<<===5>>=??5BB CCDDQEEFFGGII9]]^^3aa3eePhh3llPqq#ww#xx yy+zz{{)||}} M+)M I> I  01!N0 ! /  . -/ < <.""";:,  :  ,,LK@@#CCDD EEGGHHII JJNN OOPPQQ7RR'UUVV1WWYY]]^^!`` bbcc ddHee7ffHgg7hhii jjkk llmm nnoo7ppqq vvww'xx<zz{{'~~!/'<  NGFGF - -EDED -111 CC!/   !/0.0.0. -'B B A@A@                       ""$$))**++,,--..//00112233445566778899::;;<<==>>??@@AA BBCC DDEE FFGG HHII JJKK LLMM NNOOPPQQRRSSTT``2aa(#>? @E NO+PS&Z[\ajk)lqz{ |6 &+)      3 >#OJ88 %  $ 4g hne$=D]4KIjUUW  ==BEGJLinquU`'V(\\gcdhgijkpmttst $@DHH\q BRXY]`ef  g ikn<pFGLOQRUUXY\\^_dgiit{}   :  >  B * /C 1 1I > KJ N OX V VZ \ _[ c c_ t x` z ~e j l n o q r s t u v w z {             ^L|nj>_bF8^DKzR\^2_bhz_DJ^P~F<^^^^^^pnnnnjjjj_b_b_b_b_bKzF<v_z______V^^|\6nnnn2zjjjj8>DJ_b PbbbzV\zb_b__b__b_hK8nt8zp^^^^~KzKz<<<^<_*h@I^HXzn_bj6_bF^Kz~BhjKz_tLD__tL\__ptD:D_DnXLjjrH>^@@LXnI_PllH_bF^>~686B@@>RN_t~~_DG`_xDrF l00Hj2z_ ~~~KzhhD@@nl~R *J""Kz(\.4B:_@n@nFLRX^djFVpKv|H_H_lpvKzKzf6l6 jI $*0j^^<nI_P_tvl~l~_b___>>>>6l<BBHNTZ`F@@\flrx~>_P_t^^^^^^^^^nnnnnnj_b__b__b__b__b_||||KzKz6bR@@@@H_P h&j>_,2L8>DVJPV|\bhnKzt^zvvF_tV^j_b_^^<"V_00vz^^nnjj_b__b_88^_b__b__b__b_Kz:` >^^p$H6n"(V8KzV_tV.4z2:@FKLL~_RX^^^djnnpv|_P:vv_bVIn J 0@@r$J*D0FVI6p@@@@J~XKh<fBBHNTZ`6flllK?2_rrxF~P <$Z2 ?&,28(>DJPV\\bhntzzD_PR\^D "(.4:@FLRX^djpv|\nn^ j_$*0*06<BHhNTzZ`flr_b__b__b__b_FDFD8x~x~^^6P~FFKz<<^~^^DX_t_t_t_t_t_t  &,28LLLLLLLL>DJPV\bHh_,nt______z0DDDDDDDD8\_t_tLL__DDVVVVVVVVFLLLLLLLL( "((.4::VVVV^^@^FLLLLL_bRX^djjDDDDppDDKzKzIv|hbFrnBj DDDDDDDDDDDD$*06<BH_NTZ`flrx~Kh^>_b_bFD_P;^n__tX_  &,28___b>DJJPVV\bhznzt_zJllKzKzKzKzKz_____________ "444(.4:::::::::::@FLRXXX^jjjdjpvKK|F_b_b $*06<BHNDG`NTZ`flrx^~^_P^?&==J: = &,28>DJPV\#h.B\#6###I#f## "##x ##*G u00cY.Q:@K<gH0h<3o- 0<Dz0M<3 <@<0<0k<0<|G 0l<K 0t<l0H<0<l0<nC_0 ojY.../.(....T.T.x.>.|.|.8.6%6wJ5"4D.WS<.O q R@P}2#0(0.I*| 6*DINc7261*bHF:r5 . 9*cAd? e P6rv? cSMS.M.SRMTr#XX.-.XQ-QX-X8-8/8(8/1(-/{.K.{{K{(K(11\.6.\M6Q4..4WW48/..I.HIH8I8f..fRT ..".."]M"8,x8>(E....N2..2x.@;/-uqWixbrO~A<EO_H5J.00K<\06<"0<$}..zP. A t0F<0m<.v dVr<x@7 ("f1.[=-/GI,.Yd))8U#UB=PP44##Z#ZNZO Ou##<#>>e2nx0//0u~0E<P<Z<&LmE`<L<].hG\#K;(=cAd>kfLC">Lf L'+/27GKORW #$%&(XZdelpi)*+,-./0123456`a 2Te} $(,4>Cm89bcdefghiz{|}~ !BceGQRde . b@ .j?@?@ @ @ @ @ @@@@@b.j????@ @@ @@ @???@ @ @@@ @@j@ @.@ @@ @@ @@ @@ @@ @@ @?bb.?@ @@ @@ @bb.@ @@ @j@ @@ @@ @@ @?@  &,28>DJPV.\b.b.b.b.b.jjjjj????@ @@ @@ @@ @????j?hntz@@@@@@@@?j @ @ "?(.??4:@FLLRRXXXXX^^^^^^^^^dddd@ jpv|eeHc- reeeeeeyeueveeeeheeeeeeepemeeeeeeD"e ee!ee[=16#B##O##IDcDDeeGH Hne$=D]4KIjUUW  ==@@BEGJLinquU`*V+\\jcdkgimkppttvw $@DHH \q "EU[\`chi  j lnq<sFGLOQRUUXY\\^_dgiit{}   =  A  E * /F 1 1L > KM N O[ V V] \ _^ c cb t xc z ~h m o q r t u v w x y z } ~             :R j <#^ "$$B .#| 4;4;4% : (%t #$N=jI: $T%% % ;X $ : vI ,,,B$<H >>>|JJJjN\\\T$`Z222`fl$NDDDPPPL @444r* F> 2 x8~ X^X^X^=jj# I>D((#^$TlfV "%P$B ;X .% .% .% .%& 4 & 4 bh\4nt% ntZ`Z` Z`:::: ( jp>n &,28>\4 DJPV\:%b #^;4 "$B#| 4h;4#v$:tNntz$` I @ x #;Xx;X< I>I| "$#v:BR%# ;"#v#|#^;4#v :%t \B% $Z;F#I;F$* ##;X $NIv#"##(.40:@F %L%RR4X#^djpjpv|>NP78: ;4;X ( >D<4$``%2;4;X< $bh`f$Tlrlr "x~#^$ "NIZ|$*;4;X* &,28>DJPV\bhn#tIB=jz4#;" : ,28 I "(.4>D:@ "%;4;XFLRXRX^djp\4vv|$ ( I#:: *B r jB ;X;" . "$ 4 ;4*06< $BdH:NTT: ZZ||`f Ll$rx~5,2JP\4$$(;4;X( %&,28>DJPfV\4bhntz#^  Ix:  .:   # ( $%&$% I $$I II $Z v "II ((%#O.4%:@@@ $*;XFRLRRRXX ^^ v^d jIpI v|| $Z$Z %;X#F #46$6$#4 : $N  78;4;XB #@$*#;X$N%;40 6<B B;4$ HNTZZ :` vflrx~#;X :  > # :3*$$ &,22482> pDJPV\bhnt6$z$$ O# #=j: : p#4#4#4 "(.6$44:@FL#R#R#X^d=jj=jj=jj=jj=jpv| I I#^$T#^$T#^$T "%$B $B .% .% .%#|  4 4 4  $*06<BH% NT% rx Z`flrx~:::::: (  <  $T @@FFFFLL::&,,28>>DDDDJJPV\b||h4Dn2ptz4#| 442j"((..44::@@FFFFLLRX^djpv||$` : $$*06<BHNTTZ`flrrx~ %$T$B : & ,#I28>DDDDJJJJPPPPVVVV\\\\bbbbhhnnttzz 4 (2;X#6f#:$B$B$B .;4;4;4;4%$ 4 $B 4 5;"  :  " ( . 4 : v v @ F L RI v v v X ^ ^;X$ d v v p v j v p p v v | % $$ =j% # I I% % ! !!! !!!!$!*!0J!!6!"D"J"P"V"\"b"t"h"n"t""z"""""""""""""""""""""""""""6"## ####"#(#.#4#:#@#F#L#R#X#^#d#j#p##v#|;4;4#;4######################$$$ $$$$$$*$0$6$<;"$B$H$N$T:$Z$`$f$l$r$x$~$~I$$$$$$$$$$$$$$$8$$$$$$%%%%%% %&%,%2*Yd..E"6.Yyr-m(-::h""zmIzIE'mY.gFI8@:T<F5J"*"r"<"<6<FPLXM?"c""3"")"" #a8hQK:"mK"8"<c&"g/H""Sh 43"M"o\"3"k"" |G"l"t"l"Y. Y.-( DmhhLLmLLlH"nN"" "{o"j"Y.>Y.,Y .gY.LY.nY.y-(>-(-(,- (g-(y>6>6, 6g6yT>zI>||>||"8>8y`L"646"w(!m*zIWzIrYY.Wmm6(#"m Y..-(6RRzIzI5";Y66W"(8=,"I|""""O" "#"K""=D egggg7)""5"?~""4"1""""""N""H""$"6 "":""Ilk2 ;gggFgggggggk?gD"ggggigvgg?ggg gcgggggggUUyrr-(-(-(* m:q^mI6q6^66EETRRm^"czIzIzIqzI^E"N N 8''hEE.'**::>9-+yu*v*\W**66h<<<\x*r>*O*:6<@@@\B"""""""TTT\"""""""\ """""h"@@@@YYm_S"TT" `mK<<< 5<<`88m""":J."$""@l@l<l<<<}"""P.AtF"mvL Eoy:!-z"67"" ",ccg""""["T""="/":""S,."I"`"))')"))))F)i))F=="=6"'"FSFS'S"SOSBF;FB"'"=FFF"&FFFFZZ"ZFZO3OOO.OQFOO%F FFOF.F"F<F"F?F>>'>>>">>F>i>FF"F"F"cn/x u~E""P"Z"&"m""nE"""`"C""L"gg]""h"GYp^";"@""="ehghchF->g~84ky[ZRF>") *.2$=D]4:CINTY_du  &(?HIUUW[^_bgijllnnpqssvw~   BELLNN$&()*+%,'6UADeOTi`aoppqrsv  ((..2255<<FFTTVVY[eekk}}  (*03599;<>> BG IJMSVV\\cciilptt#$%&)*,<ZFMTYbir  !@CHHbceg"%*+  , .02 411:99;FG<MO>QRAUUCXYD\\FdgGt{KSYfno      - . N N z z                     ( V h |h V p \ 4 p  > 22  z       hhhhh 4    zzzzz          (     2 VVVVhzhzhz V V V p p 4 4 p p p   p (h h | p 4  4 z z    (h | p z  22 4 "   4     hz                      2hzhzhzhzhzhzhz 4 4 4 p(   hz   hzhz      hzhz V V ( p hzhzhzhz 4  V p  V 4 :. 42: >@ > > >hF L R HX^ T d 2 h jpv|   B    $ * 0 6 < B H N T Z ` f l r d x ~ >       > ( ( ( ( (  2 VVVV hzhzhzhz | | V V V V p p p p \ \ 4 p p p         & , 2 8 > D J J P V \ b h n t zzzzzzz zz        " (  . . 4 4 : @ F L R X ^ d  j p v Vhh | hh \ 8  > >  V     2              $ * * 0 0 0 0 0 0 0 0 0 0 6 < < < < < B BPPPPPPPPPP H H N N T T T T T Z ` ` ` ` ` l l l l l l l l l f l r r r r x x x x x x ~ ~ ~ ~ > h > >      & , 2 > 8 > D J P2 V \ b h"b\Eg"^*2&ngg)g>Y=H#KY"_KXkhhga{sg^ggg| eg|kgtge|kt5;gyg=g *g^.""D"-(MO^[PK T|zRG\4hskd/`ichg{""|"e"%"""D"j""I*";"\"z>F"FWFFFRFpF F#F#FFFFFFFFhFF4F1F FF("7"3"H<<"nhhh^)-4vQ"x &8J\n|B  "Q Yi 31  $ D  a 6"(.4#<#<$*06<E>E0>q )9  f-T 0 = o r<$N6<N`    ee 6"(.4::#1:<1#C<C  &4fT 0 3 = e o r c &8J\bb||X M "Q Yi  '$ D  "t" 6"""(.4#<#<$*06<>0>D 9" tP if-T 0 = o r c BT`lx,2@T`r* q<B|"l RNd J _"  " GC"  N^ ):4#&# { GFeF   W"""(.4=mU$*06<`,`D L"  L((    # % ) + , - . / 0 1 7  8 3 9: < <A I IB N NC  D((    # % ) + , - . / 0 1 7  =  &E ( )Z , -\ / 1^ < <a N Nb U \c ` `k f ml o st u wy y | Ep"(.:4::::::@@RpFLRpX^djpv|(o9h$"XX((.4:@FLRX^djjpv| *$r*`r06r<BHNTrTZ`flrrrx~#4*40*o.=&98(1Mb&O*%!o,ll/ll(  (  lFl& Vl ll  llll l l  2p =   m q v z ~  &,28_  V    < ST  %&VV   , 2 5 8 9 : < > A J N T V  1f : ; > H K M O b f ~ $ %& & ) , - . 0 2 5 6 ; ? E G  L  )V , -n / 1p : ;s > Hu K M O R U \ ` ` f m o w y .L4:@FLRpX^djpv|HHH~~HHHHHH~~ 0$6**06<BHNTfZ`flr~~x~"""""+"!""%"""-"'"("2" ""X1""C"""r""K"""""""F6FF1F0F'F,F$F"""""@"""`frl~rx~2 &,b828>DJPVz\bhntzd  "(.4:@@FLRX^djpv|>A#(+\8XCEJbM\U1t 66EUTC, pFFFFF FFFFE2fy34,J2(F VFF  F F FuF F  l (         ! ' ( ) X k m o p q r u v w y z | } ~  $*u"(RX^jdvjpvv|p|nFFF{FFpFsE5FFF]gFhFZuFFFjF *DFLTcyrlFgreklatn  SRB 2  "CAT JMAH tMOL NAV ROM       aaltc2sccaseccmpccmpccmpccmpdnomfraclnumlocllocllocllocl loclloclnumronum"ordn(pnum.rtlm4smcp:subs@supsFtnumLzeroR!#      $"%&NbnnT  D D f  6 J $   $ 2 p p P P.B   2 fT ((   & ) , 0 3 7 N N9     ! " # K M$ k k' p r( v w+ | |- ~ ~. / 0&*,+"#<3g456789:;LM(5jN^0:DNj|",6@JT    LG   I 3     LH   J 4 :BJRZbjrz                            :BJRZbjrz + - / . , 6 9 8 7 A C E D B ; = ? > < 1 3 5 4 2 * @ : 0:BJRZbjrz c e g f d o q s r p z | } { u w y x v i k m l j b n t h:BJRZbjrz G I K J H S U W V T ] _ a ` ^ X Z [ Y M O Q P N F R \ L:BJRZbjrz           % ' ) ( &  ! # "        $ ' )  I I I I$(,28DHLRX&( n&0:DNX        $.8BLV`jt~            $.8BLV`jt~            } "#34HI#$ `a  4R<R^(^jjyOy/yy2 - . / 0 1 2 3 4 5 6   KNOPQSVW$ ={tu*+>,-?   Q   "B*    ! $,$D2Rl|l|$2DR .    .       .        :     J          > ? @ A B C D E F G H I "$%&'()*+,-./0123456789:;<=>@^`cq  !#%')+-/13579:<>BDFH` <     J          > ? @ A B C D E F G H I ">@DEFGHIJKLMNOPQRSTUVWXYZ[\]^`cq   "$&(*,.02468;=?CEGIa B      kXKX^2B @)GOOG --%    ~01ac67Y] %&AEbw~  OP\_'/=?EMWY[]} d q  !_!!,m,-.Ds}!.Ze/ 12bd78Z^ &'BFcz PQ]`(>@ HPY[]_ f t !!!,`,n-.@t~".0[ KMHS {JL@By]><:8654320/.,+)(.Jf2ee`\`eaa^2;?.>D<RfjHhTHI#$)*&'JKLMNOPQR  k r w ~ p q v | v { w | x } y?@AO O P Q R Sstuvwxyz  ?  @  A  B  < : ; t l m n o x s u f y z g h } i j {    DE./$OPQRST-~'()* +,   -   [  O ./0123 4 < f 5 > = 7 P : ; _ ` H z h 8 9 Z j ? u S K v N J M B |6 789:;<= *+>,-?  EFGHIJK U U   W   ! XY * + ,Z[ $ % & ' ( )"#$% " klmnopq%20!1 l k W p T m d c E X q e V o G ^ L g Q C F Dr R ] y U n w x Y r \ t I i s } b a  @ A ~ {  L  M  N  O  P  Q R ! S " T # U $ V % W & X ' Y ( Z ) [ * \ + ] , ^ - _ . ` / a 0 b r T c d e s 1 c 2 d 3 e 4 f 5 g 6 h 7 i 8 j 9 k : l ; m < n = o > p t u _ `=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\] ^_`abc defghijklmnopqr~ s  t u  v wxyz {|  } ~  3 4 5 6 7 8 9 a b^*@'eU]M+3!%!!^563d9@]K_L$# +7#34632#"&w2$#22#$2|.%%.,''A$@!]L +#!#`V`pG@D  fe  KL +3##7##7#537#5373373337#~&k&_%i$t{&k&a&i&u``qeeqffqq+"(.E@B.)$#  !JI~g]L"" +5&&'55.546753&&'5654&'Af*)s5M](u]Co[.(Q#6b=jkC?dB!!:b!9F1KYKI)r/H;Ib ds * .f #+KPX@, h g _  K _LKPX@0 h g K _ K _L@4 h g K _ KK _LYY@+%$ )'$+%+##      +2#"&546#"32542#"&546"3254TWRYSUPStu{../TWRYSUPY../ujjwwjju 6\z{{zujjwwjjufz{{z(!-7}@(7JKPX@#_K_K_L@!_K]K_LY@#"53"-#- !! +26673#'#"&5467&&5466"6654&32676:Z4R= :-8,i>zF='5^=-*-(J!@0 8$F1E^#"K&887#p[L[#-L+3J(s#../+1A@]L +#`(b5 @]L +4673#&&(GLzDGFDyLGz[^wt\Xb+ @]L +#6654&'3+GLyCGGDzLGyX\tw^[$#@  GL +7''7'7'PmoLCsl3{ ;: z3+oT &@#Ue]M +3##5#5353Skkkkt@U]M +7#667/kt 5~7;4$I@U]M +75!zz9 @_L$" +74632#"&92$#22#$2F.%%.,''@KL +# 6$ @_K_L$$%# +#"&54663232654&#"1n[x0n[z*98,,89*esX­sX®z{z{z||; @ JKL +!#467'73!RI|U  B[&-@* J_K]L(&( +!!57>54&#"'>32! 6B/()N+RF[@Fe7/Y?\7i8K=#+*&#a/3W7;b`:V&+?@<&% Jg_K_L%%!%$* +#"'532654&&##5326654&#"'6632YAUZ=dtZ.d,QAKC67BE/73LF*qNn*JX TF>c9'83*t+&+$h(Y+ -@*JeKL   +%##5!533#54667#+V9V  i?yB9 &1D@A  Jg]K_L  +2#"&'532654#"'!#66,Af;8c%%h.CG<< '2`Gt7:l  l#,i@  JK PX@g_K_L@g_K_LY@ &$, ,$&$5 +4>32&&#"36632#"&&2654&#"#-Q}Y8-Ya(K<^npIvF,801"11/=ykS/y8eB#0vltCU=@4<-!@)%@"J]KL +3!5!o K_#'56@33"J_K_L,*'' +2#"&5467&&5466"6654&32654&&''>g?I7&E+?qJxP90C@i;%14#"427688 0 /9&M9AR5H/;X0fYI[U@8M&n'"%.-'"'Y'20()!: ,>@;  Jg_K_L &$, ,$&$5 +#"&'532667##"&54632%"326654&&-Q}Y8,Ya(ED[npIvF,801!20=ykS/y8eB#0vltCU=@4<-!@)9, @_K_L$$$" +4632#"&4632#"&92$#22#$22$#22#$2.%%.,''.%%.,'', "@a_L  $" +4632#"&#66792$#22#$2/k.%%.,'' 5~7;4+cq0+%%5%NcFu+/@,eU]M +5!5!+jjkk+cq0+7%%5+N؉uF):@7 J~_K_L(&" %) +754676654&#"'66324632#"&*3-'/**R+51rDhs4' 2$#22#$2$1E% / "k"dM)<4.%%.,''2O?M@ G /0JKPX@&gc_K _ L@$  ggc_LY@KI%'%%&(%%$ +#"&'##"&546632326654&&#"3267#"&&54>3232677&&#"O-D.%8 C/Ya:jH/e DvJiJ:}50vB|]W`^Xt[uAV70I;l)B1@. JfKL +!'!#3'.'44433)46;5 Zk"5@2Je]K]L"!"$!,  +32#!32654&##32654&#Zގ95#;"yXB34yhAE2@Kwh?lB|39h:V+@(J_K_L$%&! +#'#"&&54663232654&#"VZƒ tIIutIV_aTT``Vfx(\oo[[opppZ;@8Je]KL  +2####32654&*%=#ҨQ.1KAFjl1I3|213+.(.@+J_K_L%-$" +%#"'532654&&'.54632&&#"~qY3m68/%>(:5"p8d811N)+.DC7M*_q+%+!&! !1F1`kv( &, 8L/@]KL +!##5!#mL~~U!@K`L#$ +#"&533265AcHGJC2JwEwKYGNS!@ JKL +#3>76W ;AA; &'@$!JKL&& +#.'#3>73>7Ƕa  `[  hh  [6w ,4..3- zFFEApAFEE @ JKL +!##33ާpZp@JKL +3#38&L+ )@&J]K]L +!!5!5!!+V_b}bFb2@a]L +#3#32mmhgf@KL +# 6b@a]L +3#53#mm7g%'dD@Jt +D73#Fu0:b dD@U]M +D!5!aD(^B &dD@ Jt  +D#.'5)+c35.73 ',( *-&u@JKPX@g_K_L@#g_KK_LY@$"  +2#'##"&5467754&#"'663265.nuh#NDI`zz_-((L&1+l:H8( 0B-_bJ,(TYWR+(e0'"94NL"rJKPX@"_K]K_L@&_K]KK_LY@""$' +36632#"&'##"32654&J;\rt^.67<"/+<IIOUUPPQ-,7@4  J_K_L  +"&546632&&#"3267,zDyO8S,#=t=7/H""K d~<sRN-+"KPX@ J@ JYKPX@K_K_L@!K_KK_LY@"" +"&546323&&553#'#'26754&#"[st^;LrJ=21B188 ."= G"/wIIOUUPPQ-$,C@@  Je_K_L  +2!3267#"&&5466"3&&/qG?4W.)X?R~HAtN,83,wH?Hs={__@j8;1B:@7JI_K]KL%& +###57546632&&#"3|RR/W;+H&)NH((FM  m &"-+,)KPX@  J@  JYKPX@"_K_K_L@&K_K_K_LY@ $") )  +2373#"&'53255467##"&546"326554&e9 ~:c/dqsN1ampik976,PFuzw*| %+&yAQXLNF-@*JK_KL"' +36632#4#"#R2XlXC3)I*&_i?v]WH -@*_KKL       +2#"&546#!00!"//l*) )*" 7@4J_KK`L   $" +4632#"&"&'532653H/"!00!"/&6 *&U**) u"1G2R1Nl*@' JKKL +366773#'# 欝@=*3N@KL +3#3㕕N,"gIKPX@_ K]L@K_ K]LY@  "" +2#4#"#4#"#336632366]_R;2R>/rW/, @_K_L$%%" +#"&&5463232654&#">{LwD|MvD5<;55<;5B[B~ZQSSQQQQNL, KPX@  J@  JYKPX@_K_KL@!K_K_KLY@    +2#"&'##3366"32654~\rv\;FyJ :0/>31,+*&G!0wIIOUUP-+, KPX@ J@ JYKPX@_K_KL@!K_K_KLY@  $& +547##"&5463237326754&#"J<\rt]01A54))"/."F[IIOUUPN,`KPXJ@ JYKPX@_KL@K_KLY@  +2&&#"#3366   &F+qT,<4"\*<-,(.@+J_K_L%,%" +%#"&'532654&&'.54632&&#"ut9R),f'+&254A vb3\1-(H%B10/D%SY{+=.LLk$ )>@@=J]K`L  +%267#"&&5#57733#4.G*1M-GR+_$m o  NG?2stpKC"LJKPX@K`L@KK`LY@ #$ +#'##"&533265Cr[3Xj*.D2"F*&_id;;]W9" !@JKL  +333673Мi i"<6:7 N"*'@$"JKL** +!'.'##33>733>773*,?  C@  ACMAAMD"EA/2(>@AG=" @ JKL +373#'#jkss 黻9"'@$JK`L%# +336673#"&'532677g e vN$ /6 "..3UUv9(" )@&J]K]L +!!5#5!3QXXrabb,@)Jgc_L +"&&554�bV\$@==@$\V'.rr.'<0/(u(/0<n*[[*I(K'PX@ KL@ ]LY +3#kk((b{2@/Jgc_L +56655475&554&'523"('.rr.'V\$@==@$\n*[[*n<0/(u(/0<+ <dD@1JHGWg_O$$$" +D&&#"56323267#"& %3<2K;/%4=2K;- "q5  "q5 9L" @a_L$" +#"&546323#2$"33"$2w.%%.,''$F@JKPX@ pg]KLK2PX@!~g]KL@&~gW_OYY@#% +&&#"3267#5&&546675j/G,#=t<8.D'?#Wal3]=M sRN|\`^u= Q((!H@EJe_K]L !! +2&&#"3#!!56655#535466V6a'-#C /0_)/WW:ap%/^kF57 y39Gk_JY)7|G+:@7 J HGc_L$(.( +467'766327'#"''7&732654&#"\ ?H>23->I? =G>18)=G>e6&'77'&6a1>H> ?F?35,=G= 8& %J_K_L*(#!%( +467&&54632&&#"#"&'532654&&'.76654&';'"mY1W)(!E&($17FU"tc5S"&^&7(++2F%m7:.D+<8%?M]"N;1;4$HVe!+;8/ "/#m %dD@W_O$$$" +D4632#"&74632#"&())(())(" "! !" "! 1$=edD@Z.:/;Jgg g W _O&%8620-+%=&=$$  +D".54>32'26654.#"7"&546632&#"3267Pc67dNLe96cPRP-Pm?VNMgfe0\CA:2+;A9B92 6cPLe96cPPc6@NY?nT/NYYNJ~gCg;CUIMR E oT#@JKPX@gc_LK&PX@"ggW_O@)~ggW_OYY@! +2#'#"&5467754#"'663265GEB,J5AZQ0>7 NZ0,%,H=6<58:11B)(.?  0+7'77'(kkkk:: ::+y%@"U]M +#5!5kk$I1$2;idD@^-J ~g  ge W _ O%%;953%2%210/.(&$$  +D".54>32'26654.#"'32#'#532654&##Pc67dNLe96cPRP-Pm?VNM6RL0t[_>2''#,1 6cPLe96cPPc6@NY?nT/NYYNTF@/7 ¨' # Z dD@U]M +D!5!b'9dD@.gW_O  +D"&&546632'2654&#"4N--N44N,,N4 ,, ,,+L11L,+M11L+](#$))$#(+r 1@.ee]L   +3##5#53535!SkkkkkkWV0@-  JgU]M$' +!576654&#"'66323Wm-!'1<P5AO3:3Rk+0+J#?;-J5.SU'M@J%$JggW_O"  '' +2#"'53254&##532654&#"'66=P',2/V[G> A#F"/7-3)1JU=4"1 8#;D"]4 N!E(^B &dD@Jt  +D#5>7B.53c+) (,' 37NF"X JKPX@K_KL@KK_KLY@"$ +#'##"'##33265Fq;+=!YC2"I)*, +/v]W7:)@&J~]L&" +####"&&54663!:OQO)>\37dA' .l[_n.9  3+2dD@'JW`P%" +D#"&'532654&'73BU#)$-&^ 1z8>R K --L &@# JU]M  +#54667'7t&5LT *'>soh >KPX@c_L@gW_OY"$$"+#"&546323254#"hZMH]ZMG^ #BB# !U]]UU\\U11ba0(.?  0+'7'7'7'7?kkkk :: ::5$cdD@X !JU e f]  M +D3354667'735#533#'3547ut&5]~s==a 6 *'>sTJKRJP*02 F)adD@V Jh eU] M))('! +D3354667'73576654&#"'66323ut&5]m-!'1< O5@P2;36 *'>sTRk+0+J#?;-J5.b,D'+6>dDKPX@! ;/ J@! ;/ JYKPX@7g g  U g   f ]  M@>~g g  U g   f ]  MY@+,,((87,6,6543210.-(+(+*) '' +D"'53254&##532654&#"'66323!5#533#'3547G> A#F"/7-3)1J2=P(+10VMut_s==a "]4 N!E=4"1 8#;D6JKRJP*02 @!" 3+&$Cr3+&$v3+&$J^3+&$Qf3+&$j)3+p&$O++3+}pK.PX@'ee ]K]L@-  pee]K]LY@ +!!5##!!!!!%3#}VI@=>|| :Z&&zZ&(CF3+Z&(v3+Z&(J23+Z&(j3+e&,C3+ &,vA3+&,J3+j&,j3+ ?@<e ]K]L   +2###53#3#3254&:p[θCCPtt@kPr#|+||vpZ&1Q3+:&2C3+:&2v 3+:&2J3+:&2Q3+:&2j^3+?? 0+''7'7KIIJ?IJJK:!*<@9%$ JHG_K_L'-*# +#"''7&&5466327&#"4'326It_E,O,10Iu1T#)N+0/ '5`Vj,aTfo\ B5B1[o[=3@0X-LqpY8 U&8C3+U&8v3+U&8J3+U&8jJ3+p&<v3+ZG '@$geKL$"!# +###33232654&##G2udKW{1FF>B=x=jBp{4;43N5hKPX@ J@ JYKPX@_K_L@_KK_LY@ 31-,)'$. +#"'532654&&'&&54>54&#"#46632b**2804sn]7Q"'+''=0))@/5CGyMKwE^%6( !%E;SVv#:(, "&02,G]-%G*&DCG*&Dv*&DJ3*&DQ;*&Dj*E&DO*j--4?@+&%  JKPX@%  g _ K _L@*  W e _ K _LY@#/.=;7521.4/4*(#! -- +2!327#"&'#"&&5467754&#"'663266"3&&3265Ei;G?`Z)XACn#;M8/O0vv]+&'I%0+j9n9 T82<17D5%.>,:nPH?H+s23#-%M;WR)" c@ j8;1B0'"94-,&Fz-$&HCA-$&Hv-$&HJ--$&Hj&*C?Y&*vn&*J@&*ji-> ,6@3J  Hg_L"!(&!,",&+ +7#"&&5466327&&''7&&'"32654&"@n1SIKzLwDLPP.FNF&QQV->&RCO->&Rv->&RJ;->&RQC->&Rj+lU A@>geW_O      +"&546325!"&54632(())(())#')!!)'#kk#')!!)'#->;&<@9"! JHG_K_L&+*" +#"&''7&&5463277&#"4'326>{ 8!K!#'|A8J!$ ;5;5 131%iE(5)$fA0! QQ'SKC&XCbKC&XvKC&XJNKC&Xj9&\vNL$5@2JK_K_KL%#'" +#"&'##3366324#"326Lr\;JL:\rf:0/>31'-7"/IIOUU9&\jm&$L3+*&DLa&$Mt3+*&DMI&$P*-&DP.:Z&&v3+-&Fv:Z&&J~3+-&FJ$:Z&&N3+-&FN:Z&&K3+-&FK%Z&'Kx3+-&G'-w+KPX@  J@  JYKPX@'eK _K _ L@)e  gKK _ LY@ '%+ + +"&5463230&&55#53533##'#'26754&#"[st^;LLLrJ=21B188 ."%5aOOaG"/wBCHMMIIIZm&(L`3+-$&HL[Z&(MH3+-$&HMCZ&(N3+-$&HNZ&(P-$,(/O@L%&Je_K_K_L*)-,)/*/"&&%" +3267#"&5467#"&&546632!3267"3&& $8B)R~HAtMqG?4W.<,m,83oW>2">={__@wH?Hs5>8;1BZ&(K33+-$&HK.:&*J3+-+&JJ?:&*M3+-+&JMU:&*N3+-+&JN:#&* -+&J)=Z&+J3+F&KJְ3+;@8  e  eK L +3#5353!533##!!5!ZZZZZ a____a4XFjKPX@&e  K_K^L@$eg  K^LY@"" +3#36632#4#"##535㚚 Q3YjXC3LLOa )I*&_i!v]WHaO&,Q3+c&*Qim&,L3+?&*L&,M3+\&*M e&,Pq-&LP e&,NL3+ .v&,-H&LM1.{&-J3+n&,JZ#&. ]N#l&N 7Nl"&@# JKL +#'#336677_䪙F"","<)J&/v"3+?Y&Ovְ3+Z#&/ 5E#&O Z/&/' Ұ3+N&O'SZ&/N> ٰ3+N&ON ˰3+ ,@) JK^L  +35'737!Z"7YF9"`6X+`M}> &@# JKL  +35'737N#7Z"9[`7`7Z&1v3+NF&QvZ#&1 N#F,&Q JZ&1K3+NF&QKO&QqZ.!8@5 JdKL!! +"&'53267#0#330.553 0(756~v+2*AFH*?C6meNF, u@ JKPX@!_K^K_L@%K_K^K_LY@    +"&'532654#"#3366322#XD2r [2Xj#Nu"1ok]W"F*&_ia2R1:m&2L3+->&RLi:&2M3+->&RMQ:&2R3+-[&RR:%E@ #"JKPX@#e _ K _LKPX@.e _ K ]K _LKPX@8e _ K ]K ]K _LKPX@5e _ K]K ]K _L@3e _ K]K]K _LYYYY@ %%  +2!!!!!!#"&&5466"3267&&{?V>nEEnUPOU>>||}\oo[~pp  -, '3KPX@  J@   JYKPX@$e  _ K _LKPX@/e _ K _ K _L@9 e _ K _ K _K_LYY@#)("!/-(3)3%$!'"'   +2!3267#"&'#"&&546326"3&&"32654&tJ@7Z/*[A>j%#b:NwD}7b"Fx.<5P;55<;55,wH@Gs%'&&B[&&Lj8;1BQQQSSQQQZ&5v3+N&Uv|Z#&5 gH#,&U Z&5KX3+,&UK.&6v3+-&Vvw.&6J!3+&&VJ.&6z-,&Vz.&6K"3+'&VK#/&7 ##&W /&7K(3+:&W'//@,e]KL +3#535#5!#3#yyyy#|~~| I@FJ e]K`L %# +7535#57733#3#3267#"&&55 >GR+_$.G*1M-a^?2stp^aH o  NGHU&8Q3+KC&XQVUm&8L3+KC&XL|U&8M3+KC&XMdU&8O3+KCE&XOU&8R3+Kn&XRU&5@2JK`K_L#&%" +3267#"&5467#"&5332653 $8BHGJC01/*dW@7;wKYGNS2@k#-GKC"&XPL&:J3+ N&ZJp&<J=3+9&\J"p&<j3++&=v3+&]vr+&=N3+&]N}+&=K-3+&]KN+@( J_KL  +"#46632&&!#/W:0B#(&JFM  m ` %R@O J!Ie_K_L %% +2&&#"3##"&'53265#575466->#!oo$N@3$RR,Q m &"p<2R1u"1H((EN  '3S@P.J ~ egf L )(#!''    +56673&54632#'!254&#"3'.'0 8@C64H 45/J2 X5 $$ +6>>5$~.99 +/&* ">I@< ; ) JKPX@: egg g _K _L@> egg g _KK _LY@,$# GEA?9742.,('#>$>""    +#56672#"&546"32654&2#'##"&5467754&#"'663265 8@c0 4HH46CC6nuh#NDI`zz_-((L&1+l:H8( 0B $$ 5>57>>66>E_bJ,(TYWR+(e0'"94}&vx3+*j&vP:&v3+->&v.#&6 -#,&V (^)dD@ Jt +D#&&'#5>7S-0c?<c0-74 ++ 37(^)dD@ Jt +D.'536673-0c<?c0-^73 ++ 47(^s'dD@U]M +D!5sgg(^.dD@#W_O#" +D#"&'332667jSVdS/0"I\ZK (f (dD@W_O   +D2#"&546y!00!"//*) )*(]E 9dD@.gW_O      +D"&54632'2654&#"6CC64HG5]>66>>57>E(,dD@!JHW_O%" +D3267#"&5467 $8B@.A"&oW>2,L 6(]4dD@)Wg_O"""" +D663232673#"&&#"(K422IL340]NIMJ(^ =dD@2JU]M    +D#5>7##5>7&21O$" /&21O#"  (,' 46 (,' 46^ -dD@"JU]M +D5>73.^?? '\/cmF !OdD@DJWe_O !!    +D#56672#"&546!2#"&5460Cr$$##($$##F !N' V V "! !" "! !" &$S Ѱ3+9+yxx3+h&(sS Ѱ3+&+sS Ѱ3+ ',S Ѱ3+&2=S Ѱ3+,'<S Ѱ3+F&uOS Ѱ3+F&T$Zk%Z;K2PX@]8K9L@]8LY@ +!#ԗ}vGJK2PX@8K^9L@b8LY@+!5.'{  {VWvw(''(Z(+=Z+:/@,e_@K_9L$%&#+#"&&54663232654&#"#5IttIIutIV_aTT``V4fo\\oo[[oppp-|| e,Z.:JK2PX@ 8K9L@ 8LY@ +#.'#6=@@<TZU0Z1( eK2PX@ e]8K]9L@ea]8LY@   +5!5!5!<esQN||||}}:2Z>K2PX@]8K9L@]8LY@ +3!#!Z56LZG3&/V@   JK2PX@]8K]9L@a]8LY@ $1+357'5!#"&'633&6EEwt|}/7p<-/%jK2PX@! gg 8K9L@! gg ]9LY@%%!  +#5.5466756654&t=Iz[\{H=ubMS\\SMXKvF-^O2nn2P]-FvKXR=CS-SC=R;57NK2PX@g8K9L@g]8LY@ +##5"&&55333266557;wz9&M<6N+Xw<=vV:?{>:!VJK2PX@_@K]9L@a_@LY@ !!+"!53&&5466323!56654&Uc8JȵFUSiiSUHK9cWidV(+dZJJ[e+'Udhj&,j3+p&<j3+-q&}S&&SNF&S2N&SFPF&T-q+".KPX@ J@ JYKPX@"~_CK _9LK'PX@&~;K_CK _9L@-~~;K_CK _9LYY@$#+)#.$.  "" +"&54632366733267#"&'#'26754&#"`vyh:J { ,2> L>01A54 ))) zC"u$."0wKRPTUQNq-N@KJg_BK_9K=L)'&$ --  +2#"'#466"32654&##532654&SGp@KDUama>EvF2D>=K4#518+U@HU  Z[itQe0t73=6>0v9.//8""@ J;K=L+#466733>778 ЛP   P")YU"T])HD;G -> -3@0J_BK_9L)'  +2&&#"#"&&54667&&54632654&WDh5;-T+( CDZTyLvD3W6.FyR;(:46<6i4".xN~4dHE]8S7IM'E4/?C?4G&,)E@B !  Je_CK_9L)(%,%$!+#"3267#"&54675&&546632&&#"3RMB%s =2 =>NF"w,"2JK2PX@ ;K9L@ ;LY+336653#j91%]T"DKŎlT-G4+@(Je]:L!%!j+74675&&54670##5!#"33#"#6654&'&&-M=38DI"0* %6]:8OQRUK"=*YE*,9dsB[ >25?mg8)*,g<<++ @-,X#&Q  f->,R "KPX@J@JYKPX@];K_9LK2PX@];K9K_9L@ ~];K_9LYY@ +%267#"&5###57!#{ <EQrW]sk k LTP@2r;=,!;@8J~_CK_9K=L!!#"+#"&'#0#4632%"32654&=zh&H |IsB659800)=C~IHSLWWL-G, +@(J_CL  +2&&#"#6654&'&&5466>[S+%C>7"?)YE*,9dsD{,'q`_-/ B/-]$)U  p_x:-y#!@];K_9L%%&#+%#"&&54663!#32654&'#"F>xXPxCJ_$46>=6 LEDn@?{Zd|9m&d"FVPA2FP"$@!;K`9L +"&&5332654&'3Abm,38:; EtI)G?Vh@tBAsF--&,@) J_CK=L&&*+54632#5.546"6654&&l&*M7nUm~RMN{G>DQ'-F4fBMH `c{]~D>tZV2'/dK+H+V)$K"PX@"!J@"!JYK"PX@_CK`=L@;K_CK`=LY@ $$+2733267#"&''#'&&#"566u/:&$_$ +BK3A% ,)>1l!tHG&w F0@-J:K;K9K=L+6654&'3#5.53PK&NRSI>PsJ^BFg|:8ydUG5*"+4@1 J~;K`9L++#%%&+#"&'##"&&5467332655332654&'1bI@II@Ib1-2-!!-2- "HPQ|F8//8F|QPHBJI[@::@[GJB&jqFP&j ->&RSFP&S5*&SZ&(j3+ KPX@ J@ JYKPX@ e]&K_.L@$e]&K'K_.LY@  +"&'53266554&####5!#32)4,). ֪pxe } #>+#L~~e\?ekZ&`v3+:F@C  Je_-K_.L +"!!3267#"&&546632&&Qk5c[0a93b>wJSt@l46,QV[U|W_[nl^{.6 e,j&,j3+.-"+KPX@ JKPX@ J@ JYYKPX@ g]&K_.LKPX@*g]&K]'K_.L@(g]&K]'K_.LYY@+)%# "" +"'53267>7!32###%32654&##P'!  8_z;ǎ  +K.>GMC# |=T g8b?juL.loc&>X.,79$ZKPX@g&K^ 'LK'PX@"We&K^ 'L@#ge&K^ 'LYY@%! +333332###%32654&##Z8_z;.=HMC#8b?ju4|,79$-@*e]&K'L#!+#32#54&####54ּeq"'~e\+#L~Z&v3+ &&63+Z0 #@ &K^'L+!##5#3!3ђҗL$ZQ 1@.g]&K]'L !+3!!32#'32654&##Z93EOVJ'}8b?ju|,79$Zk%Z`03@0Q]&K]'L +3#5!#3>7#!_A7&B4 '6 NJ҄~FGZ(%@" J&K'L+333###sWZZjj.]+?@<&% Jg_-K_.L%%!$&)+#"&'532654&##5326654&#"'6632GfObiQ}.NP"_U|iC7##ZJ>;+6WA<-Z&&3+Z @ J&K'L+!##33jZQ@ JKPX@]&K_'L@]&K'K_.LY$(+!###"'53267>7!  +K<'!  L.loc&>X. |=T gZU0Z+:2ZmZG3:Z&/7 -@* J&K`.L%$+#"&'5326733667DgT>92,  |Eb4 1#7:,-/r;Z0 MK'PX@R&K^'L@a&K^'LY@ +%#5!3!3xL5~)@&Jh&K'L##+!##"&5332673~?i5dq09*T4aZ'44@Z @&K^'L+!!33333~ޘޗLLZ0FSK'PX@R&K^'L@a&K^'LY@ +%#5!33333FޘޗxLL 1@.g]&K]'L !+3#5!32#'32654&##J93EOVJ'L~8b?ju|,79$Z0 6@3g&K^'L    ! +3332#!3%32654&##Z1c>|(CMOH!8b?ju6|,79$ZQ +@(g&K^'L !+3332#'32654&##Z93EOVJ'8b?ju|,79$#]F@CJe_-K_.L +"'6632#"&'53267!5!&&0^-05vCJw=c39a0\d5^Vzn[[[|S]Z!KPX@e_&K_.LKPX@#e&K_-K_.L@'e&K_-K'K_.LYY@ $%"#+#"&&'##33663232654&#"EldIlD!NSVLLTUNfo\O`膝[oppp?3@0Je]&K'L'+#.54633##"33J:&K;@>AG: /O:ci6<*1/7*-D-A+4@1(JHg_.L%#+++4676673>32#"&2654&#"-4n:"QP2B$ +?*bsDxOy/;+5 7&5G  !HD'yv]}>5@RAM( 3^;NC""/@,Je](K]'L!$!$!*+#!!24##3264&##3262769E1jV@e;OiX/131be*7,> A1/J*"?A2l N"@](K'L+##"pN"<"3@0Q](K]'L +3#5!#3>7#39P.$2p *&"K17Rp[G-$,Hi",@) J(K'L+###33VܟЋПɚ‹"  &,*J@G('Jg_/K_.L%#**+2#"'532654##532654&#"'66;g?<1#8!9x\J"c8=T:7JQ4;'](,/o,@21: 1)-M/"{#Ag!hN"#@ J(K'L+3#54667#"24)B9"N &&LNk" @ J(K'L+3##3ߕ""7"Q@  JKPX@](K_'L@](K'K_.LY##+!###"'532>7!7 +M?4! Yw $^N"'@$ J(K'L+#467####3pӈ" (L `!K-"rNH" '@$e(K'L +353#5##ЕЕ""->,RN>"!@](K'L+###>ƕ"N"NL,S-,F"@](K'L+###5!Np9"\-.@+ J(K]*L+#5&&546756654&ݎALJCCHJ ss ru ZACYFYCAY="[N<" #@ R(K^'L+#5!33332ڕP"NK<B"/@, Jh(K'L#"+326753#5#"&55B+J%#Z9Uf"GWYN{" %@"(K^'L +!3333{ӕ""NNN<"-@*R(K^'L +3#5!3333{P "K"NN" 6@3e](K]'L   $!+32#!#5#32654Ci~ypfh+8"PQP^pƁ&<N" 6@3g(K^'L    ! +3332#!3%32654##NH}xp?E,7eC"PQP^"g&<NC" #@ e(K^'L!"$ +32#!34##326i~ypefh+8OPQP^"<$,F@CJe_/K_.L +"&'53267#53&#"'66324Q#$P,3=b#A*\4HrC t:Ccy f2xkN@,_KPX@e_(K_.L@'e(K_/K'K_.LY@ $%""+#"&'##33663232654&#"@vebdgIsA07600760sx"jrB~ZQSSQQQQ" +@(Je](K'L!#&+3#7&&54633#5#'335#"*A|aRb6+Sf(&MCRW˭"''-$&HjF,@ JKPX@/ e _ (K ^'K_ *L@- e  g ^'K_ *LY@&$"! ,, +"&'532654&#"##53533#366322#.*C3LL Q3Yj#Nu"1Q56]WHaOOa )I*&_i2R1N&v-,F@C  Je_/K_.L +"&546632&&#"3#3267?~D{R[S+%Cd b0N(#K m}4$jyc}r-,VHL@&*jiMU"!KPX@ J@ JYKPX@! g](K_'LKPX@+ g](K_'K_'L@) g](K]'K_.LYY@!!##$! +32####"'532>7#32654"Eyum~t +M?4! ?A)4"PQP^Yw $^Ɓ&<NU"fK"PX@ g (K^'L@# We (K^'LY@$! +32##5##335#32654"Eyum~ݪ?A)4"PQP^"Ɓ&<FNk&v9 &\&N<R" #@ (K^'L+!#333## ڕ"NZ1a%@"]&K'L+!#!51TaʗNFKPX@&K](K'L@](K'LY@ +##!5N"&:C3+ N&ZC&:vb3+ N&Zv*&:j3+ N&Zj|p&<CQ3+9&\C6(E@U]M +75!(pp(E@U]M +75!(pp(E*dD@eU]M +D!5!!5!aaZDD @]L +'6673/k 5~7;4 @]L +#667 0k 5~7;4t 3+ @]L +#&&'7k/4;7~5  $@!]L    +#'667##'667/y/;4 5~7;4 5~7 $@!]L    +#667##667 0k[ 0k 5~7;4 5~7;4t  3+< @ JKL +'#5'37Ȣ,v7)@& JKL +7'#75'75'37'+vvphvvh0H @W_O%" +4632#"&0Q;&@&R:;QmTGD8SHH9&': #/7?KPX@2   h g_K  _ LKPX@6   h gK_K  _ L@:   h gK_KK  _ LYY@;9810%$ =;8?9?530717+)$/%/##      +2#"&546#"32542#"&546!2#"&546"3254!"3254TWRYSUPStu{../TWRYSUPTWRYSUP../M../ujjwwjju 6\z{{zujjwwjjuujjwwjjufz{{zz{{z.7@L +3#`.$@!]L +3!3 Á(.H0+7'(kk::(.H0+'7'k :9&@A@KL +#Atu63zmGQ)&f 3+7@4ee]K L +35#53!!!!3#ZIIW||WW(('Z@WJ  e e_ K]L#"!  '' +2&&#"3#3#!!5665#535#535466X9\'-&@"#) )_0(WWWW8bp%/7V8W>y=$W8V8JY)Z` ,@* !JKPX@/ eg ] K  K`LKPX@3 eg ] K  KK`L@6   ~ eg ] KK`LYY@% ,,)(%#      +2####32654&3#3267#"&55#5775~k) CF>#%<#FSGR+wh?lB|3944=tf! e H^52s 40`@]J+I e f_ K_L-,%$#"  00 +2&&#"3#3#3267#"&'#53&5447#53>2S'0": ;N &CE.uC:9A P|qEAV Ww }vWVPr=*4k@h  J ~~g g  gW_O31/-)'#!  +"&546632&&#"3267##"&546323254#"Ma-N27)&!!#32tuYLG[YLE]#??#qVW@N# L 5++2 P Y6U]]UU\\U11ba0)o@ ' JK PX@!pgW`P@"~gW`PY@$"+%2673#"&555667546324&#"669&eRdWf--`\O]oj=/*]11_icb> ` ]QUIaz1r(2 $%WB!+/`@]JgU   g  U ]  M,,#",/,/.-'%"+#+!!+3330.53##0%"&54632'254#"5!B sH]ZMF_[KBB# y8%32!32675&&#"5Us;.K\.IvDlN-IV"#;TTL42GN~HHhD C|U%<6%>%>&"C*6C@  =%JKPX@#h ]K _ L@'h ]KK _ LY@"877C8C20 ** +3354667'73"&5467&&5466326654&#"2654&''utn&5]RV.$)F*?X)!5\K6 *'>sTG8)01%$177%/0)8J   U'+DP]0KPX@! W?2 J@! W?2 JYKPX@5  h  g_K_K _ LKPX@9  h  g_K_K K _L@=  h  gK_K_K K _LYY@+RQ-,((Q]R]LJ:8,D-D(+(+*) '' +"'53254&##532654&#"'66323"&5467&&5466326654&#"2654&''G> A#F"/7-3)1J2=P',2/VJutRV.$)F*?X)!5\K"]4 N!E=4"1 8#;D6 G8)01%$177%/0)8J   /^!:FS@   M5( JKPX@5  h  g]K_K _ L@9  h  g]K_K K _LY@*HG#"GSHSB@0.":#: !! +33"&'532654#"'73#6632"&5467&&5466326654&#"2654&''ut#CB&.R " 5 AZ]RV.$*E*?X)!5\K6 ^#>ZBEBGNG8)11%$177%00)8J   E #/<@ 6JKPX@+ ~h]K _  L@/ ~h]K K _ LY@$10 0<1<+) # #   +33#5!"&5467&&5466326654&#"2654&''utFRV.$)F*?X)!5\K6RZIG8)01%$177%/0)8J   3^  cK PX@W_OKPX@_&L@W_OYY@ "#+#"&&'33267 0fVXc*/4+7 4O,*O67$'4XS @J]L  +#5667S(W !M( V #T ^K @J]L  +#5667K( V !M(rO 6@3JUe]M   +##5#533#547r=ts= >JJKP*02 ])]LB@?JegW_O#%$2 +#6632#"&'532654#"'7@ AZ]Y#CB&.R " 5LZBEBGN ^#>cL*@'JU]M +#5!KFRZIeV$19@61JgW_O,*$$  +2#"&5467&&5466"6654&32654&'?X)!5\KRV.$)F)V77%/0)8JG8)01%$1M   )E +:JV^bfosw}!K PX@B / .JK PX@B / .J@B / .JYYK PX@5  p)%!&&%p  4321e  U W  g7  geU6"g$"#!%"!e/-+(&''&U/-+(&&'^<0;.:,9*8 '&'NK PX@5  p)%!&&%p  4321e  U  g7  ge6"g$"#!%"!e/-+(&''&U/-+(&&'^<0;.:,9*8 '&'NKPX@5  p)%!&&%p  4321e  U W  g7  geU6"g$"#!%"!e/-+(&''&U/-+(&&'^<0;.:,9*8 '&'N@5   ~)%!&!%&~  4321e  U W  g7  geU6"g$"#!%"!e/-+(&''&U/-+(&&'^<0;.:,9*8 '&'NYYY@~~xxgg-, ~~x}x}|{zywvutsrqpgognjhfedcba`_^\YWUSOMJH=;7631,:-:*($"   =+53#5!53!53!5353##53#53#"&54632"'532655332##'32654&#"32654###53#5332654&##53#53533!5353!53!5335355^j5566G>BB>>BB>2 =6T575.e "" "" ' +T66j55B$266j55`6^x_56^666666^6^BQQBCPP22-! )!"',-33--336K򄄄_55_555555)d+C@@JGU_O*($"%-+ 54676654&#"663232654&#"56!++\P*X"(!>!& ())(66{">1CJW"7'##%o&,K 6@]@ZJ~~ g _ BK_9L87>=7@8@0.*(!66 +23##"&&54654&#"'6632326544'.5466"&&aYq? G?FuWW\# %K,+3*2GH}B,[J#$TG FHRpDz_6/J)3 Y.+A#,pyAe9/M.p4"QXtK'PX@  J@  JYK PX@~8K9LK'PX@~@K9LK2PX@~@K8K9L@~@K8LYYY%%+6676632&&#"#37<9/& 6:Dz,& p]u;".D@A J~] ;K_9L*(%$!%% +##"&'##"&5467#57!32655332654&~om@II@nn UYZ-2-!!-2-"p-a/y8//8y/a->2p.]-IG@:CC:@GG,`ZU&0vU3+N&Pvs&$F*-&DF}+ 9dD@.gW_O      +D"&54632'2654&#"6CC64HH4>66>>57>E:W$/@,JK_K_L$(&# +#"&&546632665332654&#"IttIIuV)C?V_aTT``Vfo\\oo[4/G0 ReNhppp-t$/@, J_K_L$*%" +#"&&54632665332654&#">{LwD|7b"(! #F= 5<;55<;5B["! K4 1R<D'QSSQQQQU.@+ JKK`L#) +6653#"&533265$" +YQAcHGJC\ I4 6Z= JwEw?OEKJK&tcJKPX@]K`L@!]KK`LY@#" +#'##"&5332653665 +[Rr [2Xj*.D2%$t 7Z> qF*&_id;;]W9 K4vST>)@&JW_O%& +#'6654&#"56632OU % 0DDL#HR6Z&(CF3+Z&C3+-$&HCAN&C$(@%# J&K'L$$+3.5336677&&'33653#&&'+M;"'4 < #7#/1[a)GSB^tѮ=&\&5b:dͽKm@DN"%(@%!J(K'L%%+#&&'#.5336677&&'33667N&L<9g!@4 +": %)/"`c0h23HY/:r+j2RETφt9@6eg&K^ 'L! +3#53533#32#'32654&##}}}93EOVJ'p^^pD8b?ju|,79$s@@=  e](K^'L$! +3#32#!#535#32654i~yp~~fh+8bpcPQP^pbd&<Z&KPX@# $ J@# $ JYKPX@" e_&K _ .L@* e&K_-K'K _ .LY@! && +"&&'##33>32&&#"!!3267mMeiYd9q11,X*Pe +.R;/^82a O`WI{UO~7W2N,$KPX@! " J@! " JYKPX@" e_(K _ .L@* e(K_/K'K _ .LY@ $$ +"&'##33>32&&#"3#3267Tq ll EkB4\*A#23=3,P$#Q sx"T`(f 95oC9t 0@- Jf&K'L +#####3'.f12e]344[ *0- ,,,0)" ,@)](K]'L +#'##5###3'.J&'JZ""V0*)'+0Z dJKPX@ f &K'L@  U  f &K'LY@ +#######333'.f12euk]3444[ *0- ,,,0)N"aKPX@] (K ]'L@" U] (K ]'LY@ +#'##5##7##337#3'.P Q_Y[ s ""V0**/3@0 J]&K'L+#'&&'##7667'5#ѻ@TJ<)$&),]W"4F<& !'=F4enZ #F@C# Je] &K'L"!  +#'&&'##7667##3!'5#޻ARJ<)$%*0RZ^IZc10(8L%%' /!o=_\*h^^U|iCHX  YG^w  p [A0H)/83/v*%+ e&F 43#UKPX@MRJG  F 'J(G@" M RJG  F 'J(GYKPX@-  ~  gha_.L@4  ~  ~  gha_.LY@ONDB><;964/*%#"UU +2&&#"#"326632&&#"#"&546632654##532654&#"'667&&'53> (6I8. 64yf*+$,$-%$& .!X<]P*dVB?:7JQ4;'](,=#1`4-:JB51: 1)-M/   p RD3J)!Ag!h 6 23#57tF:7@4e_-K_.L&#+#"&&546632%"!&&267!IttIIutIPX g WPTX Yfo\\oo[[ZPPZbXXb->, 7@4e_/K_.L%"+#"&&54632%"3&27#>{LwD|MvD___B[B~HnnqqR@  JK'PX@_&K'L@&K_-K'LY@+"#36677>32&&  S*<1 / R0, D,@&&D(>X. vZ&2@/J~(K'L +2&&#"#336677> * ќd  <$7&s" =;3@&d }3+Z&e W:':E@B%:32J_-K(K_.K`*L%#&&&#+#"&&546632326654&&#"%336673#"&'532677@ss@@ss@H>@GG??Hg e vN$ /6 fo\\oo[[oKl::lKKl::lq..3UUv9(-,&R\W: -6@3(#JgW_O'% +"'.54676632'66326654&'#"'9c> #$ { "" FB@F $1FAB=8 `d  •8y]\x%x\]y-zL..@+ ,&JgW_O**)%+#"'&&546766324&'#"&'663266zzk#: e~yn""g$'&#%(  )&v7vvw;ST:=UV:-(^@O3 N4 C@ \ J ~gg_+K  _-K  _.L*)ZXSQLJFDBA><861/)^*^((#!#"%+54>3233#".#"56654.54632"&&54632&&#"32675332654&#"'6632#"&'h)0&IR36K4(&#%**EjA'V52256654.546"&546632&&#"3267'332654#"'6632#"&'%JR36K4(Y)0=&))E*'_z[S+%C>7A8*9sD{,'qRSOQ  m}43/v 0+'''7'77'7>Y$b#X?X"a#v$P<:*7*75310.,))'%#"  ""(+D6632#&&#"6632#&&#"!6632#&&#"6632#&&#"!6632#&&#"6632#&&#"!6632#&&#"6632#&&#"2205'% 2205'% 2205'% |2205'% 2205'% K2205'% 2205'% 2205'% Y+45*,35*,35*,35*,35*,35*,35*,35*D#,5>GWdD@L75,+('# <;21JeU]M???G?GDC+D#'667'&&''766&&'%&&'5&&'%'66#667 D !40'"$P0"U)^$&X&&X&)^$2(!5j0"U'"$P' !/ )^$&X&k$P0"U'!50( D !/ !/ D"U'"$P0'!4A&X&)^$Z0%M@JJ g   a&K'L%%$#"!  +"&&'3326737#467##3333Yb*.4+7/f\JW+N68#'44O,-W1r).l+N< % JK PX@$ g   a(K'LKPX@&   a _&K(K'L@$ g   a(K'LYY@%%$#"!  +"&&'3326737#54667#333eYb*.4+7/fCG^*O63('44O,?;">=KQ>@;e g &K^'L%! +3#32###535#32654&CC'3EOVJ|L8b?ju|Jr,79$C>@; e e^'L$! +3#32#!#535#32654㸸i~ypLLfh+8maPQP^*am&<ZG5@2Jg]&K'L'2!'+'###323227'7654##G+1+J8)9A< %K1xE9e!=7P w56F,hNL,,|@ ('&JKPX@_(K_.K*L@!(K_/K_.K*LY@$!,, +"&'##336632'"3227'76654z;FyJ:\r&!.M5H:0/>>R4 +0G!0Mq$<:DIIOUM<@- -@*e]&K'L +!3###53ėCC||#|+" -@*e](K'L +#3##5#535CC"yjssZ"z@ JK2PX@#g]&K'K_*L@ gc]&K'LY@ ""+"#!!6632#"&'532654&C. @"6o_:KyE6E#>#HKt|!L^iH iQc^N 7" G@DJg](K'K_*L 4%&"+#632#"&'532654&#"#$%HyJBmB >:2DGS "yv?|]az;  GRCR"08@5 J&K^'L +3#5###33𥛒RjjsWZZ<"5@2 Ja(K'L +3#5###33VɇFЋПɚ‹"  .]&^&,&^Z01@. J&K^'L+3#5##3ZjZN<".@+ Ja(K'L+5##333CߕѤؑz" Z-@* Je&K'L+%#5'#375373#'oA==A]URkNk"3@0 Je(K'L+73#'#5'#375PdrF''Lb0"13@0 Je&K'L +53533#3##0VV |BB|Zj k=@: Je]'K(K'L +3#3###535㚚ѤߕLLOa HaO +@( J]&K'L + ###5!6jL~Z" +@( J](K'L +###5!ߋ9"p Z050@-ea&K'L +5#!#3!33嗗4N<"0@-ea(K'L +5#5##33533IЕЕ"KZB -@*e]&K'L +33!!##!Z6~4N" -@*e](K'L +3335!##5#NC"pNZ3'w@ JK2PX@$g]&K'K_*L@!gc]&K'LY@'''%'2 +6632#"&'5326654.#"###{&G3j[7KxF6F">#+B&*BK!'!L^iH 0T6AM' LN V"!E@BJg](K'K_*L!!$%&2 +6632#"&'532654&#####/  EuFBnA> :1EA@"?|]az;  GRCRN":3?O@L=  Jc_-K_/K_.L%&4%%#%&+3267#"'#"&&54632&&#"3227&&546324&#"66$0  !4TGBiK G&)VKhP*gW2Y6*KC`?v0 Zk u txsuFqh,bU5==3;VW-n,3>`@]9")#J gc_/K_.L544>5>-+'%  33 +2&&#"327&&546323267#"&'#"&&5466"6654&,;!%:/=. RP+I-0  '$F6%Ms>6q,, oYRTH>2QW#L"@J(K*L+#53366773jԤV  W"PPp1@. Jf&K'L+35#535333#휜휜~&L~>"/@,Jf(K*L+3##5#53336677>ԎԤV  W"pp"PP0/@, Ja&K'L+5##333ASާpZ<r"/@, Ja(K'L+5#'#3733Xssjkq~Ļ 01@.R]&K^'L +5!#5!#!33˳L~~2L< "1@.R](K^'L +5!#5!#333|ƕppK508@5Jha&K'L##+3#5##"&533267~?i5dq09*T4aZ'44@<<"8@5Jha(K'L"#+3#5#5#"&55332675B#Z9UfB+J%"KWYG5~;@8Jge&K'L+##5"&&5353667~?6AFrD.7A:!6 QJ'34 @<B"<@9 Jhe(K'L2+#5#5#"&5533536675B+=  Uf&%=*" vjWY&!}v Z)@&Jg&K'L##+36632#54&#"#Z?i5dq09*T4aZ44NFKd&-@ JK,PX@&h _ -K(K_.L@)~h _ -K_.LY@('+*'-(-$" && +2!32667#"&&'#"&546733366"!4&zDc`7o\,kkW PP r MajP_s#Zf%+O`D;3%~UPNW,")@  JK PX@(ph _ /K_.L@)~h _ /K_.LY@$#'&#)$) "" +2!3267#"&&'"&54733366"3&&tJA6Z/)ZAO|KKUdi.=5,wH?Hs5mT2;.# noj8;1B0d(/@ JK,PX@#ha _ -K(L@&~ha _ -LY@*)-,)/*/&$ (( +2!32667#5&&'#"&546733366"!4&zDc`7o\%hN} PP r MajP_s#Zf%%~D;3%~UPNW<,#*@ JK PX@,p h _/K_'L@-~ h _/K_'LY@%$('$*%*"# +&&'"&5473336632!3267#"3&&fTjKUdhtJA6Z/>WA.=5ue2;.# nowH?Hs8;1B e,&&3+i &&Z&z@"JK2PX@&~|&K'K`*L@#~|d&K'LY@&&&%'!+32#"&'532654.#"#36677 0k^:KyE6E#>#AR,GO$/$Dx\iH ^\AM' 2N e"=@:Jg(K'K_*L$%#+%#"&'532654&#"#3732cBmB)2+1FPM, ϳAk?(`~> ~ FNNS"8s02KPXJ@ JYKPX@Q]&K_'LKPX@a]&K_'L@!a]&K'K_.LYY@ $(+%3#7###"'53267>7!W\  +K<'!  ÂL.loc&>X. |=T g<"K'PX@  J@  JYKPX@Q](K_'LK'PX@ Q](K'K_.L@!a](K'K_.LYY@ ##+%3#7###"'532>7!7GC +M?4! mYw $^Zd@ JK2PX@e&K'K_*L@ec&K'LY@%$+#"&'532655!#3!@wR1K"A-@C嗗bVK aQN H";@8 Je(K'K_*L%$+#"&'532675##335H?mF&9:0;Е"Vr8 AL"Z0F*@'ea&K'L+%3#7#!#3!3W\嗗4N<"0@-ea(K'L +333533#7#5#NЕGC"K50~2@/Jha&K'L##+!##35#"&5332673~~y?i5dq09*T4RaZ'44@<<B"8@5Jha(K'L"#+##35#"&55332675Bp#Z9UfB+J%"1lWYGZ0.@+ Ja&K'L+!##3333#7#4>7#ΩΣW\0>D<"R?D: N<"0@- Ja(K'L+%#7#467####33GCpӈm (L `!K-"rK e,&$&=3+* &D&&$j)3+*&Dj}*j-D&(&3+-$ &H& P C@@Je_-K_.L   +"5>32#"&&55!&&267!>pVNjGuRNnzD cMMaPW&#\oqY_t#ZfVONW+",)P&jm3++"&)j&j3+i&j.]&j3+&&j(H@E  J~|]&K`.L%$%+#"'5326654&##57!5yzAh~^2r/>G[p<am^>c9'1,4j}"A@>  J~](K_*L&$)+#"'5326654&&##57!5Xh.@f{]0o.=D"UL:"a Eh?Em?'$:"$<#jrZm&L3+N&LZ&jx3+N&j8:&2j^3+->&Rj:b->,c:&bj`3+->&cj#]&j3+$&j m&L3+9&\LP &j"3+9&\j &R3+B&\Rf5~&j(3+<B&jZ0 (@%a]&K'L +!3#5#Ԓ}5N<" (@%a](K'L +#3#5#䆆"p"Z0&j3+N&jz&{_s"@ JK2PX@-  ~ e](K'K` *L@*  ~ e d](K'LY@  +"&'532655#5#535!#3#3)  CC|Hh!@syjs_VPI@F J~&K'K`*L +"&'532655##3333#Jާ#Ku"1%pZ2R1c"s@ JK2PX@ ~(K'K`*L@~d(K'LY@ +"&'532655#'#3733(  SssjkqoHh!@ VP/@, Jf&K'L+3333####7ʭ‹ |.="/@, Jf(K'L+3'3733##'#7#2ijkjfsseL֮pܻ-$ 2@/g&K^'L      +!"&5466333'35#"T>e<3'JVOuj?b86|$97,-+G-I'>@;J~g&K`.L%#%$## +326553#"&'#"&546633#"3265&*,&j3_U=ss;z_8#CM2('2 27g]%$uj?g<r,<4--P#/K'PX@ J@ JYK'PX@&~ _/K`.L@0~ _/K`.K_.LY@%$*($/%/##$%## +326553#"&'#"&5463230&&55"326754&'+*%{i>H8?woZ8Ia20c:/-%"27zg] #."%3UPIIOU <-K.PX@+*J@+*JYK.PX@e_-K`.L@&~e_-K`.LY@(&! --+2326553#"&54&##5326654&#"'66nYAVY ##+'~iqxSgSSAI473JL*vYQJX TF+27g]pj,=j.&+ e(,,K'PX@*)J@*)JYK'PX@e_/K`.L@&~e_/K`.LY@'%! ,,+2326553#"&54&##532654&#"'669c=7/7='+*%{ggL>KHDK27%X&,.k,@21:  7/ 27zg]HH4/g!h 0%F@C#"Jea_-K'L  %%+23#5#54&&##5326654&#"'66sYAVY&XJYYFP 8<6QL,zYQJX TFN/j.&+ e(&<,$F@C"!Jea_/K'L $$+23#5#54##532654&#"'66;g?8. 6PMJO4;'](,/o,@21: 1)2ğJg!h)<@9J~]&K`.L))$(##+326553#"&&5##"'53267>7{&++'~iEi;  +K<'!  #!27g]'TF.loc&>X. |=T g\"!6@3J~](K`.L###"+%326553#"&&55##"'532>7!('+*%zhDi:z +M?4! $!27zg]'UFYw $^ZK PX@e&K`.LKPX@#~e&K`.L@'~e&K'K`.LYY@## +326553#"&&55!#3!$))${gCf;%"27g]&UE~Nm"KPX@e(K`.LK'PX@ e(K'K`.L@'~e(K'K`.LYY@#" +353326553#"&&'5##ƕN)$ygCf:ƕ"D27zg]'TF*":"3@0Je_-K_.L&%%%+!#"&546632&&#"3266'#U!K|[UqPv04!^ICX*+\J?G7!3r3#  +K<'!  Ï#Ku"1%L.loc&>X. |=T g2R1"" KPX@JK'PX@J@JYYKPX@"](K_'K`*LK'PX@&](K'K_.K`*LK2PX@-~](K'K_.K`*L@*~d](K'K_.LYYY@ "" +"&'532655###"'532>7!3$)   +M?4! {Hh!@Yw $^KVP.&$ *.-&D f&$K3+*>&DKW&$V3+*p,&DVT&$W3+,&DWU &$X3+*Fg&DXV&$Y3+*y&DYT.&$' J^3+*.&D&J3 [&$Z3+*L&DZX&$[3+*L&D[W&$\3+*n&D\X&$]3+*y&D]X.&$'Mt 3+*.&D&MI VZ.&( g-.$,&H `Z&(KT3+-$>&HK_Z&(Q:3+-$&HQ5Zl&(VP3+-s,&HVW&(WR3+$,&HW[Z@ &(XP3+-Gg&HXWZ&(YP3+-$y&HYWZ.&(' gJ23+-.$&H&J- ` e&,K3+9>&*K .e&, H.&L :.&2 -.>,&R n:&2K3+->>&RK_:&2V3+-v,&RVZ:&2W3+>,&RW[: &2X3+-Jg&RXZ:&2Y3+->y&RY\:.&2' J3+-.>&R' nJ;:W&Gv 3+-&Hv:W&GC3+-&HCO:W&GK3+->&HKe:W&GQ3+-&HQC:.W&G -.t&H pU.&8 K.C"&X vU&8K3+KC>&XKmU&Iv3+K&&JvU&IC3+K&&JCbU&IK3+K&>&JKpU&IQ3+K&&JQVU.&I K.&t&J w.p&< p9"&\ p&<K^3+9>&\KCp&<QE3+9&\Q*-bw&Bu"^, /@,JeL +6673##&&'#56673 v<J+O44O99- 3_** J""J^, =@: JeL    +&&'5356673#&&'=v+99O453 - _ J""J **"^g%n@ "JK PX@og_L@g_LY@%%!   +2#'6654&#"56#&&'#5667u.7 >#  C9O44O9g#'!9 >s"J ** J"$^y&x#JK#PX@  gh L@) ~W g`PY@&&"!"""" +#"&&#"#66323267#&&'#5667r352*=52 2)4?E9:EAy1B1B"@ $$ B"$^L @ JK PX@pdLK,PX@~dL@"X`PYY@    +#5667#"&'332679@ [SVUI8+)9L : 5II\ZK*),'$^L @ JK PX@pdLK,PX@~dL@"X`PYY@    +#&&'5#"&'33267 @9%[SVUI8+)9L5 : II\ZK*),'$^n"@  JK PX@pgcLK,PX@ ~gcL@*~|gW_OYY@""   +2#'6654#"566#"&'33267*14[SVUI8+)9n!!6 3kI\ZK*),'$^y#?@< ghc L##!"""" +#"&&#"#66323267#"&'33267s442+=62 2*6UVS[K9)+8y1B1BBOQ@"$#@  J`*L%%+4&'3#"&'5326d&"W%3B8$ o6 ;*2>W}2@/J]'K_*L +"&'532655#53b3# #Ku"1%}2R1/&7z&WzL) JKPX@,e _K]K  _ L@0e _K]KK  _ LY@!%#))  +"&'###53533#36632'2654&#"z5AVJC8 gu8dBjz|08=%b71KM :@7 JK_K`L    +"&5336632'2654&#"O|N;[sBsL367/;47 ;"/_~>xLWSQKGSH#C7@4J_K_L  +"&'532654&#"'66329X.3S+^``X+L$1.q=kII sp{\lo]:o)L@I&  Jg_K_L%#)) +2&&#"&&#"3267#"&&546632546|' 1(Q'W\U^+X3/\9oDNl-,Zo r(qqr}[nl^ PL-K(N@K %&J_K_K_L#! (( +"&54663254632&&#"&&#"3267,zDyO  VE& ,#=t=7/H""K d~<)\P rLnRN$ [K PX@p]K]L@~]K]LY@ 6! +3#"#&&5466332#'3254&## v#RDp[θ3AhcQN!.M/Pr}vp-$ 9@6g]K]L    +!"&5466335!5!'35#"H?g73'JVOri?d:}6|%97+-+%KPX@ J@ JYKPX@"]K_K_L@&]K_KK_LY@!%% +"&5463230&&55!5!#'#'26754&#"[st^;LrJ=21B188 ."%3IpG"/wIIIQPKPQ-%>,k" "3+; /@,e]K]L  +35!5#535!5!;}||6P+Z,J@G%Jg_K_L  ,, +2&&#"33#"32667#"&54675&&5466KW8B*`8@B&_T@;Je]K_L  +"&'53265!!3#>, _ r||\T:o/[@X+  Jge_K_L*(#!// +2&&#"&&#"32675#5!#"&5466325466' 3!T.Ba5&RB ,8zLVx0-*Fo r!p24gTi.11/ hzgv]W B PbkqB>BL&U+@( JK`L  +"&&5332673Q/$'B #QG#& w j7@4 JfKL +3#!575#535'5eW\\WW\\WV(|(VV(|(VZpKPX@ J@ JYKPX@_KL@K_KLY@  +2&&#"##3667766C& &x@ Q-W wr-..l=PNl<@9J_KKL +2&&#"366773#'#46*  "欝@a r>*3S\P @ '@$eKL  +3#5333#ZPPQQ4pTpb+KPX@ &  J@ &  JYKPX@~_KL@~_KKLY@ ++$(%' +3''7&&#"566327327#"&''&&'# dS#  2GU]S' 7=?/  eR {41S>%s =2 =>U"hJKPX@]K` L@]KK` LY@ "" +"&533265332653#'##"&'# \oW?5WB2r Z5>QV ak#xVP#x_X6L++0*+/!:@7 JKK`L !! +"&'53265330.53##07& 6^ r*?CR6*AFp\TNF,:b: ,X@ JKPX@_K_L@_KK_LY@ $'"$&# +#"&&5466326632#4#"32654&#"GqqGGqOx(#dF?`6g+3 QZ\OO[[Qfp[[qo[/+'31hRy)d8ppp-V,)3@0 J_K_KL$&#$%" +#"&&546326632#4&#"32654&#"*vJrAw:]#!X4Xj*.8 16511651@~^&()%_i/;;#@%QSSQQQQ"bK PX@!pg]KL@"~g]KLY@" %6! +3#"#&&5466332##32654## v#RD4yhA2@KxEN!.M/wh?lBz39hNL#/T@Q J_K_K_KL%$,*$/%/ ## +2&&#"36632#"&'##46"32654* 1L:\rr\;Ia:0/>31 r7+"/''A\PIIOUUPZ;@8JgeKL! +##33232654&##Q9%=#]1KAFI.ddjl1I3213+*&7@4$#J_K_L! && +23267#"&54676654&#"'66h{4R-=N446h4,o@zy\RIG/,)P2-4qe`AR32)%)~l_Re#.* $v&,&7@4$#J_K_L! && +23267#"&5467>54&#"'669]6KN53X'Z-OknqSF03&!%G((1g, B3EI 2q'SOGP k&/o$m@  JK2PX@g_K_L@gg_LY@!$$  +23267#"&&5#"&546"3354&\O$.B'3R/JDH6`Sv o  NGME6.GR$U@R!J~]KK`L $$ +"&'532655#"&&5#57733#3267)   1M-GR+_$.Hh!@ NG?2stp VPVNK PX@p]KL@~]KLY@ &! +3#"#&&54663!#C v#RDL!.M/~#P@M J_K]K_L ## +2&&#"3#3267#"&&5#575461 (9$.G*1M-GGg r8,p o  NG?+5\P/5@2J]K_L  +"&5#5!#3267R] /R^~~wr !5@2J]K_L !! +%2654&'5!##"&&5467#5!Uc8J8FUSiiSUH:K9cthdV(+dZJJ[e+'UdgU]@ JKPX@_K`L@K_K`LY@  +"&5332654&#"56632wHGJC* @$MQA wKYGNS#u QNJwEppKPX@  J@  JYKPX@~KL@~KKLY@  +23#'.#"566N:BVn +?8$L+) u  b,&KPX@J@JYKPX@~K`L@~KK`LY@ && +2&#"#"&'532677336677>/ &sY( " +9 ٢V  6 &:, s%>sS\v2-B!>" 8"+7@4Je]K]L +37!5!3#!!57#>y]s_a}b|}b"=@: Je]K]L +3#3!57#537#5ZLUQiOM"azatrXair('3E@B J~]K_L  +"&5467'5!!#"3267RsgE arj#:%6K~0 ")M@J&'J~|]K_L$" )) +"&54676654&##57#5!3267[uYhF Gf7ED 3+.F I@Z6]:(E aroaB$*4* [/"A@>Je]K_L  +"&'532654&###5!!328m%FHG[JIYKp?   1;85~~6dGq&"A@>Je]K_L  +"&'532654&##5#5!#325l""l/CNQD_TCj= {""ppa!H5(?2stp#);3/K-NL,lKPX@ J@ JYKPX@_KL@K_KLY@  +2#3366"6654&~>\4IyJ :1_r2,?qLN^G!0wKJ jP8K\@KL +33\k\&2bK"PX@"e  K]KL@ ee  KLY@ +3#3##5#535#5357kaVaaVa9Z&''=K3+Z&'']K-C&G']yKsZ.&&/-5Z&/M5N&OM1Z.&1--Z&1M-N{&QM&$K_3+*&DK4&,K3+o&*K:&2K3+->&RK<U&8K3+KC&XKOU&8z3+KCW&XIU&8z3+KCq&XIU&8z3+KCr&XIU&8z3+KCq&XI&$Y3+*W&D.&$Y*W&D.}m&L-3+*j&L:'X@U  %Je e_K_ L$#"!  '' +"&546632&&#"32675#535#5!3#Vx9n-2!T.Ba5\c,}}AA8z pZy,&RP:m&2'LP3+->&R&LiP(&K'3+&K$Z&'=Z&']-C&G]y:&*v3+-+&JvZbKPX@ eKK`L@$eKKK`LY@## +333332653#"&55#Z+11,w}}v @:">54&[tSs6H?GCi<3Շ`(\/~oa`}DCGZ&1C3+NF&QCb&$ 3+"&D _&$ Y3+*&D .!&( ^3+$&H YZ&( -3+-$&H (e&, 3+7&* &, 3+Y&* :&2 3+*>&R g:&2 3+->&R 6F&5 3+&U /Z&5 R3+>&U U&8 3+=C&X zU&8 z3+KC&X I&LJ'%@"J! G_L +5>54&''>54&#"'66323vT!-((Y/RwA>77b,B9Ju4-1Ep촀854&#"'6632D%NY%2%(I",)b5@g;*&,5Dzw!TG%4  j&,#l&N<.JQ>GG>>G-H&<@9JhK_L $"& &  +"&&547&&553326553'254#"9MyF;-&44'1;AIDzOuvu ;sT8fKccGJIGddKeiLTtW&R6:&23+->W&R6:&2N3+->&RN:&2->W&R6pm&<Lk3+9&\LP&":@7  JgK_L""$# +'667&&536632#"&'72654#"lF   *?EQO*E /"%$.8 7 B>;G a(N,)3KPX@1'JG@1'JYKPX@ g_K_L@(gK_KK_LY@+*0.*3+3$%$* +'667&&554&#"#3366326632#"&'72654#"F  &)>-rU1Sd)?EPP*D /"%$.8 ~;;]W"F*&_i B>;G a( *L@I (Jg]K_L"!'%!*"*$# +'667&&55#57733#6632#"&'72654#"|F  GR+_ *?EQO*E /"%$.8 ?2stp B>;G a(-".:P@M !JK_K  ` L0/$#64/:0:*(#.$. "" +"&&546323&&55336632#"''2654&#"!2654&#"&Jp?s[;JJ;\rBrJ}:~_/"5 5"/_~>\\xKZSOQSWLLWSQOSZK-,".:P@M! J  _ K_KL0/$#64/:0:*(#.$. "" +2#"&'##5467##"&5466326"32654&!"32654&Iq?r\;JJ;[sBsI}:<367/;030531:/76,>~_/"5 5"/_~>\\xLWSQOSZKKZSOQSWLE@B J fKK L +!'##7##37337&&''4UaU4a0MX* t"B@? J]KK_L  +"&&'&&##5#5!327@L+-3:7:,##6*E)*.XXra H&8* t-@* J_KL  +2#>54&#"'66Ji8[[JN8+:051j7^54&#"'66Jh7Z[JN8+.P51j,7^01,."F r`P%5"/yUPIIOU A@>Je ]KL  +2####53#32654&*%=#ҨQPP.1KAFjl1I3{=|213+,yKPX@ JH@  JYKPX@e_KL@ eK_KLY@$4 +##5#535336632&&#"OlNNqT7   1U ?aa\*<,6p5@2J fKL +##'#53'33737#phg330044gkaa____f9"&9@6J fK_L#"%# +33733##"&'532677#5336677#65<2W vN$ /6 r]6 J"aUUv9(a.11.K2,D\" "3+-+,~KPX@ J@ JYKPX@_K_L@!K_KK_LY@  +"&54632373#'#'26554&#"[st^;L ~rJ=41B188 ."FG"/uJJOUSRTONL,!y" "3+NL!-@JKPX@*~_K _K_L@.~_K _KK_LY@#")'"-#-!! +2&&#"36632#"&'##46"32654&* J;\rt^.67 r7"/+<Q\PKQTVUPPQ,7@4  J_K_L  +2#"&'532654&#"'66yz7I##F/7CE:9* Y,RQRPs-,&1U@R * JGg_K_L('-+'1(1&& +2&&#"6632#"''667&&5466"32654&E;N,": B>O0KU8[6d;  J F~j';C"-,sPU  !K@9E'$!1%Z:d;#,-%2T@Q"#JK_K_K`L'&.,&2'2  %% +"&55467##"&5463230&&553326726754&#"<\JJ;[st^;L0=21B188`P%2"/."%3 r]IIOUUPPQ-"/KPX@ J@ JYKPX@"_K_K_L@&_K_KK_LY@$#+)#/$/"" +"&5463230&&554632&&#"#'#'26754&#"[st^;LXU, rJ=21B188 ."$2[S rG"/wIIOUUPPQ+",GHO@+",>@;Je_K_L  +2#"&55!&&#"566#326 R~HAtMq`G?5V.(Y25+:,={__@wH?Hs1B8&,-O,+?@<Jg_K_L'%$"++  +2#"&&5466"32654&##532654&Un};24HAvNQKNP;Q$>&.C=GG=>,KL18 367O*<~bZ~BnWUCI#!g#1"=@:JeK`L  +"&'53265#53533#"6 *OONN&Uu"1 aa2R1--8c@`&J_K _K_K_L/.31.8/8%# -- +2&&#"#"&'53255447##"&546323&&5546"326554&C, :c/dqsN1ampbe9Xik976 ruzw*| !+&P8[SBPXL-+,J-,F@CJe_K_L  +2&&#"32675#53#"&5466U1Z2,B))E*?Hh+rAA,s"H8LX\cPJ9"#2@/ JK_L## +"&54673366773'254&'EH"ɜa  `"JD"P@1b<A<A7d)=RY6?"!?9,.9=@:( J_K_L64" .. +2&&#"#"&5467'&&#"5663236776632654+ "N JEEHK& )*?$  #:,n"f$F*8RP;,D"d! n'$2#& 0#)*&K*C"K" "3+NF";@8J_K_KL""")%# +34632&&#"36632#4#"NaN* R2XlXC3Q\P r"?*&_i5v]WNF.S@PJ_K_KK_L+*'%!.. +2&&#"3632#"&'532654#"#46* 2nXj#N@2#XD2a r $=P_ia2R1u"1ok]WQ\P1 ?@< e_KKL      +2#"&546##5#5353!00!"//NNN*) )*OaaN"U" &@# JKL  +!57'5UVVVV"H**HH*>*H<@9JggKL"#2" +3&#"#6632233273#"' $ IH4  " IF3 [4JL95JM>@; Jg gKL$! +3#"&5463233#354#"#F?<5bb+#$=/2= yMq3 NO+@(  JK`L  +"&533267\J0`P8 rN!S@PJ~K]KK_L !! +"'5326654&&##57!#3!{]0o./-*'')*&_idvTOv]WN,/@  J% IKPX@$_ K ]K_L@(K_ K ]K_LY@-,*($#"! // +2#"&'532654#"#4#"#336632366]_#N@3#R;2R>/rW/,c-,,%KPX@ J@ JYKPX@#e _ K _L@8e _ K ]K ]K _LY@!%%  +25!#3#3!5#"&&546"32654&5:z=KvC};55<;55, p`ppr B[xQQQSSQQQ.,+C@@ J~_K_L&$! ++  +2#"&'##"&5466"32655332654&&wSme@II@emWsRf/*+-!!-+*/f,Q_q8//8q_Qx6\7=D@:``:@C<7]7-x"U" "3+x`KPXJ@ JYKPX@K_L@KK_LY@  +"&'7326653#'#G   &F+qT <4\*<"">@; JK_K`L "" +"&55467##"&'73266533267ZHN7   &F+2`P*3&7<4 rN,`KPXJ@ JYKPX@_KL@K_KLY@  +2&&#"#3366   &F+qT,<4\*<N,}KPX@J@JYKPX@_K`L@K_K`LY@ +2&&#"3267#"&53366   &F+0\JqT,<4 r`Pb\*<Ky.+@(J_KL  +2&&#"#46$6) _.y-#gfaC.+@(  J_KL  +2#4&#"'66[_ )6.afO#-yT]" 3@0Je]KL ! +3!2#'#32654&##TawA2MV+3')d"RS?F/'"'T]"GM"@ "3+-,5B@?() J_K_K_L%,%$%" +%#"&'3267#"&5532654&&'.54632&&#"tp!   "/KB,f'+&254A vb3\1-(H%B10/D%SYH&h WN+=.LLk$ )>O7@4J_K_L +2&&#"#"&'5326546,  K@/X ry2R1r [SO$L@IJe_K_L  $$ +"&'53265#5354632&&#"3#8/NNXU, NN Kr 5p[S rp2R1O,7@4  J_K_L  +"&&54&#"566323267@K  .VW..P2r R\E rO&I@FJg_K _L" &&  +"&546334632&&#"3#'2655#"5IGEIXU, DERgG.6EQ[S rMH[R ,W" "3+@@=J]K`L  +267#"&&5#57733#4.G*1M-GR+_$y o  NG?2stp"l JKPX@  eK `L@#  eKK `LY@$ +553533533##'##"&553267#KΕNNr[3Xj*.:4aaF*&_i1 ;;C?o" 5@2 J]K_L    +"&&5467#5!32654&'5!#DW}C='xjN@@N45u(9C} zJHHJ?Y npbJJn<KU, pKPX@ J@ JYKPX@_K_L@K_K_LY@    +2#"&&53326554&#"566K  $JRTXXra h ?" ;@8 JGg]K]L"#$" +'67#5#5!36632##73254#" O <+VA6Bj[M TM "WXXrZRMC7UB)'%"")5@- '# J$GKPX@)~]K_K_L@'~g]K_LY@+*1/*5+5)) +"&&546326654&&##57!5!&&''267&&#"^L@g.(YJ2Ri3" D "ZZD&F(!4G:@H4+ &B(cra Gi<9M ?  m "'-@* J_KL  +2#>54&#"'66Ji8\[JO8+:051j7^d-50:+8OJ[\;n "k5*A?t*wV.)?%,LmC YO6> 514G#n!g!#J@-z.]@Z+  Je_K_K_L)'" .. +2&&#"&&#"32675#53#"&5466325465% ,B))E*?Hh+rAAc#V rVi"H8LX\cPJ,\PNH"' &K@Hg _KK ` L " &&    +"&54632"&5463333#'2655#""//"!00IGEIDERgf )**) G.6E"MH[R*"Nl" "3+N"@K^L +333N"Pr-$0P@MJ_K_K_KL&%-+%0&0$$%)$' +5467##"&546323&&554632&&#"26754&#"J<\rt]01A541"/."5"[S r[IIOUUP ?@<Je_KL    +23##5#535>54&#"'66Ji8\[llZZJO8+:051j7^j15/9+8OJZZll[\8j"k 5*A@aaC*xU<:9820*6+6$"$$ +'67!'##"&546323&&553!36632##%26754&#"#3254#"O J;[st^;L<+VA6Bj[M =21B188/BM "WG"/."7ZRMC7UB)IIOUUPPQK'% #6KPX@ 0J@ 0JYKPX@_K ^LKPX@)_K_K ^L@'_K]K ^LYY@&$43$6&6 #" +!"&&55#577336632&&#"#'32654&&'.5467# 3M+GR+_*3\1-)G%B10.E%|w*'253B }!PD?2stk$ )=0RWp+:-A,5g@d%&0J~_K ]K `K_L.-21-5.5%#%%# +#"&'532655#"&&5#5773354632&&#"267#' K@/G*1M-GR+_XU, .$;2R1r L  NG?2st-[S r# 4w7CKPX@ ( A 5J@ ( A 5 JYKPX@)  g_K ` L@?  g_K]K` K  _ LY@#98?=8C9C31,*$" 77 +"&&5#57733#3267&&546632&&#"6632#"&'%2654&#" 4M*GR+_%!C F}U;N,": B>M.KW7\6Df%1p~"->0 "OD?2stp#@"d;sPU K@9E('('mw7KPX@"#  J I@"#  J IYKPX@._K _  K ]K_ L@9_K _ K ] K ]K_ LY@1/-,+*'%  77 +"&'532654#"####57546632&&#"3366323#XD2RR/W;+H&) [2Xj#Nu"1ok]WNH((FM  m &"F*&_ia2R1N)KPX@J@JYKPX@K_K_L@ K_KK_LY@ )) +"&'#332654&&'&&54632&&#">d.ek5/.1GCn^2Y--%B!;-,ALx 7 KDJNk& GAYXN 6@3 JK]K^L  +33!3%#N[areK N@K J~ | KL    +#'#3737#'#3737fk<=jd]>?f:@^fk<=jd^=?f:@PPN0@-~e]KL +!#5##!#5##NvvvvC,"KPX@ J@ JYKPX@_K_KL@ K_K_KLY@ "" +232653#5467##"&554#"566@VJ*.D2M:Xj+ .,R\;;]W1)(_i<r ,.KPX@,+J@,+JYKPX@!_K_K`L@%K_K_K`LY@)'#! .. +2326533267#"&55467##"&554#"566@VJ*.D20ZHM:Xj+ .,R\;;]W r`P*3)(_i<r 3zGK)&f 3+3zG3)&f 3+GM)&f 3+3mGU)&f 3+gGF)&f 3+8gGH)&f 3+7gGN)&f 3+&gGZ)&f 3+rgG\)&f 3+    ?' *dD@gW_O +D2#52654&#4HH4'>57>E?' *dD@gW_O +D"&5463"34HH4?>75>E)8dD@-  JW_O%% +D5654&#"'6632Nf)!A(RM9>f7 NJ8.D31G9@ 3+! 3+ 'dD@Jt +D73#' o(p;II / /3+(T Z(^Bv(^BC(* Z ְ3+(MsL 3+(4B (4B 9,dD@!JU]M +D'37YYY苋9dDt +D'3Y( y y3+( y y3+~  3+~  3+  3+M dD@U]M +D#53>(; rgG0)&f 3+3GO)&f 3+*mGV)&f 3+tgG[)&f 3+5Gb)&f 3+NT,dD@!U]M +D!#5!nBPNT0dD@%Ue]M +D!#5353BBPNT0dD@%Ue]M +D!#533BFB(PNT0dD@%Ue]M +D!5#533BBPNT&dD@U^N +D!!533TBBnNT&dD@U^N +D33!NBBNT*dD@Ue]M +D33##NBBB(9K ۰3+(S*5 53+  (v'dD@Jt +D'373OXYNކ(v'dD@Jt +D73#'(1OXY܄(#0+'57#k1kE>?(#0+57'5(E>?Ek1(BC 3+(GR@ 3+(R 3+(1Q ԰3+9̰3+(&dD@U]M +D3##(q55(-dD@"U]M +D#5#55q5( ,dD@!U^N +D333(5q 5( &dD@U^N +D3#5353Φq55(0IdDK PX@nU^N@U^NY +D!53!53B8M9Хcc(0FdDK PX@nU^N@U^NY +D!53!B8Хc(K 1dD@&JH GU]M +D'57!!#O1;DK* @J]8L+6673#& F#W7V !U $ 5JKPX@ ]=L@U]MY+#56673& F#WIV !U ,$-,&FNc c3+,&$Nb b3+,,A)4O@L"2Jgg_BK _9L+* 0.*4+4&$) )%&&$ +6632#"&&546632#"&7"32654254&#"Y:'S^'@S Ͱ3+t&@j3+-"6@3' JK2PX@$~_;K9K`=L@&~|_;K`=LY@1/)(!66+"&'532655&&5467#>54#"'663233267)  8G%D -4N,- '( Hh!F Y]/%ew?vf'YM#$%j|?D1VP:T JK2PX@_@K]9L@a_@LY@ +2#5&&5466"32654&vGIu\ZY\]XXLWtvWL~\PP\\PP\->,4@1 J_CK]=L +2#5&&546"32654&7MvDeYUiz;55<;55,B~ZrrxQQQSSQQQ:ZV@JK2PX@_@K]9L@a_@LY@ +2&&#"33#5&&54665k11(P(W\\b2vM{WUQZ}YJ-2,&4@1Jc_CL&&+"&'532654&'&&546632&&#" =6,0#5buI~P:^+,'H"=/YExp jekEq-, K>RVZ K PX@ pe]8K9LK2PX@!~e]8K9L@ ~e]8LYY@ +3!!3#5#Z~x|uN" VK PX@pe];K=L@ ~e];K=LY@ +#!!3#5#xsps+F@C()Je_@K_9L&$+++"&54677!76654&#"'6632!3267@O A 1GM J . <92 f f B:*!J i-,=@:) *J_BK_=L'%,,+"&54675654&#"'6632%3267KPdn  2HF P*x! .CB,?^! f E:/=RiQ@  JK2PX@_@K9L@_@LY@ +!>55'7&&''7&&#"'6632<, -35N?#jOpI&(_g3TKj.vLo #q'cZ?@  H=L+6654&''7&''7&&''%,(nF1*%Ne)U61JbH",KPX@ +  !J@ +  !JYKPX@_;K`9LK2PX@_;K9K`9L@~_;K`9LYY@,,%&%%+3>54#"'663233267#"&&5467)%D -4N,- '( $2R1%ew?vf'YM#$%j|?D1i%WL/.>,&4>@;, J_CK_9K=L('0.'4(4&&+2#"&'##6654&&'.5466"32654&@JrBzh,K./6R- %$6R7B{S&9K711,C~Z,)-   $OeJx.ocLWWL-,FM:b-,$,ZGNL:Z&ZUPJK2PX@~8K9L@~]8LY@ +3333#4>7###ZľV6R@D=MX\"N" X JK2PX@~;K9K=L@~];K=LY@ +373##'Ńˋhd=,(O@L& J~e _CK _9K =L#!((%# +5#534632#"&'#03#2654&#";;;|IsBzh&H k80086599ahC~Z"5a9^LWWLHS#Ch:Z&&y#C&hyM:V4-+,T: N"Z &",@)JfKL  +33#'#73'.' őƀ))G(  "ރ (*.("8@5ee ]K]L +!!5##!#3#3%35#:x#0"]|]+k--8?@&   JKPX@#  e_K _L@( U  e_K _LY@><:975%%$"#%#" +3267#"'#"&&55!&&#"56632>324&#"766#326kvv],%'I%0+j9n9 U:Ei;aG?`Z)Y@Cn#:L9/O0%.>7D50/1<WS)" c@ :oOH?H+s23#-%M:#85-02A8 l"&K'PX@! e]K ]LK.PX@&U e]K ]L@'e e]K ]LYY@%#$!$!% +3##!5#535!24##3264&##3262UE1jVEE@e;OiX/131be*7-Z,/J*Z?A2l ;,7@4  J_K_L  +"3267#"&&546632&&ACICI#D(&G-Vo6=uT*T&'?eWYa`FTSH\V%"@]K]L!$!" +##324&##32%zRM@3"[W"%" ?@<e ]K]L     +2##5#535#3#3254&44?[[3S"]]][WV" )@&e]K]L +!!!#3#3B̾"]z]&,*J@G#Jg_K_L ** +"&'732654&##53254&#"5632Mo/,(]';4QJ7:T=8c"J\x9!8#1cF7!@ !3+s8C@ C3++," "3+9")9@6JgK`L%#))#) +#"&5467&&55332655"32654&!)10ryxr/1*v,22+]:54:;44"A1HL5XjiX3OF2BA/66/A4//55//4- >,$@!_L  +2#4&#"#467MwC5<;5,A^URRU-> !@`L"" +#"&&'33267>zLvD5;:5 A}YOPPOV" 2@/g]KL       +2####32654& lc)_Q3v6(2:-"ZO0S2"](,)'"8@5Je]KL' +37.54633#5#35#"-odvJ8;.21 $;-KP0!%%*";@8JgK^L  +!"&54667'3353'35#"do-Jv;8212PL-<$ ]*&&!"@]KL +!##5!##v__KA"!@K_L#$ +#"&&533265A.o_bm+4701"IuEEuI)G??G.&R Q&Y@ Y3+ @ ǰ3+)rUP)@ 3+"FY8@ ",'@$%JKL,, +3334>733>773#'.5#: >;  <'    )"EA/2(>@AG޿ 8B@..@C8"]!"H@E  J~|]K`L$$$ +#"'532654&##57#5_`t{bK'Z%I6FY/"ITHH``/%#(P^1*%;@8"#J_K_L  %% +"&546756654&#"'66323267`_JGA1%# ?'#)X2R`IEuR+R("X QB4DH YKB8BF 62_*'+@(JK_L($%%" +%3267#"&&'#"'53267&&546632O#0 ' 24#1M-/ .$/>.T99S.B."Y/+>-Y!.2k?0M--M0?mV"@]KL +##v"^<" "!@ JKL +33#.' wh  i"L .01- V"@]KL +!###!vv<"V"5"+@(gKL +##5"&&553332655.l^k^l.oCFkCF"AY.-YAB*&*A "Q@  JKPX@]K_L@]KK_LY$& +!###"'53267>7! v @G    c.vn&FN ].?kMG$)&f 3+DG)&f 3+:G%)&f 3+ %lKPX@# e]K]L@!g e]LY@%$ $! +535323###5732654&##32654&# .\`:,[Oc9+!'*4@,##/G0<%G':BHp :G')&f 3+:FG()&f 3+&2Gp)&f 3+&G*)&f 3+:G+)&f 3+G,)&f 3+G-)&f 3+:G.)&f 3+:YG/)&f 3+:*G0)&f 3+:G1)&f 3+:>JKPX@KL@]LY@ +333#5667#:X}X;AT=&G2)&f 3+"G)&f 3+:{G3)&f 3+:G5)&f 3+ kG7)&f 3+7G8)&f 3+uG:)&f 3+XmGD)&f 3+1mmG )&f 3+imG!)&f 3+9mG)&f 3+3~GE)&f 3+iGG)&f 3+dmGH)&f 3+cmG))&f 3+QmG*)&f 3+PmG)&f 3+imGJ)&f 3+.gG)&f 3+3GN)&f 3+3NmGP)&f 3+3zmG )&f 3+umGR)&f 3+1mG$)&f 3+umG)&f 3+uG)&f 3+3~mGS)&f 3+GW)&f 3+1xgGX)&f 3+*YG )&f 3+1LgG<)&f 3+rgGY)&f 3+ EkG)&f 3+3G~)&f 3+qgG)&f 3+uG)&f 3+mG)&f 3+kG)&f 3+/hFL)&f 3+3FU)&f 3+1xFX)&f 3+rFY)&f 3+3kF~)&f 3+qF)&f 3+&tF)&f 3+F)&f 3+F)&f 3+K,'.KPX@  J@  JYKPX@"   f]K_LKPX@&   fK_K_L@0   fK_K_K_LYY@(((.(.&###%" +%!3267#"'#"&&53326536632'&&#"G?4W.)X?EVHbk*0705@"Dh:34*:>Is\&6EuI)G??G.;oN1B8;L-9@ # & JKPX@4  g_K _ K]K _L@8  g_K _ K]KK _LY@8620+)!""" +#"&'##&#"#6632533273#"&'366324&#"326Lt^.6+<u6JL"R6JL 7"/7w`PGOUU--:KPX@'  * J@'  * JYKPX@1hK_K _K  _ L@5hK_K _K K  _ LY@#/.64.:/:)(%$"! -- +"&5463230&&55&#"#6632533273#"'#'#'26754&#"[st^;L $ IG3  %ID4 rJ=21B188 ."%366JL#R6JLG"/wIIIQPKPQ/c@`# JI g  g_K]K  L//-*('"%&" +35&#"#66325#57546632&&#"3#3273#"&'f %IE4 RR/W;+H&) $ IF3 6JLfH((FM  m &"p6JL,.7AK PX@ >/ -*' !J 5I@ >/ -*' !J 5IYK PX@-  ~  g  _K] LKPX@4  ~  ~  g  _K] L@8  ~  ~  gK  _K] LYY@888A8A<:31.."$ +35#4675336632366326673#5&&'#5&&'54#"54#"NI?0rW/5<;57"d( F`Fp5iM_t71irV@;7II7:A8KPX@1+ 2 7 J@1+ 2 7 JYKPX@.~   K_K ^ L@=~  K_K]K K ` LY@8864/-*)"' +7&&5#57733#537336632#4#"#3267#"'#]GR+_ #kR2XlXC3 .G*%:Kv?,?2stpT,,"9 *&_i?v]W o IU"7@4 JfKL +#!575#535'5!NOVVMMVAVGat*HH*tai*HH*i"7@4  JeK`L%# +#3267#"&&55#5353Eb$.C'3Q0NNGa; o  NG;ay,!'KPX@   J@   JYKPX@*   e _ K _KL@.   eK _ K _KLY@'#"%$"'#' !!  +23##"&'###5353366"3&27#~Sn // rU;FNNyJ 30SU 1,tqavz+*&aG!0w77nw:=" A@> eK _ L    +".'5#53533533#'2655#HH`9NN̕NN0mW/24 %@Q+aa:g@x8118" 'R@OJ  e]K  _ L"!%$!'"'    +"&&55#53667#5!!&'5!#3#'267!DW}C->,xGHu, <-;LL >>>NL&3KPX@J@JYKPX@, _K] K_K_LK2PX@0 _K] KK_K_L@-c _K] KK_LYY@('/-'3(3&&$%(' +36632#"&'532655#"&'##"32654&J;\r HF(   .67<"/Hl$zVPh!7+<IIOUUPPQ-]%2KPX@ "J@ "JYKPX@(K_K _ K_LK2PX@,K_KK _ K_L@)cK_KK _ LYY@'&.,&2'2! %% +"&546323&&5533#"&'532655#'#'26754&#"[st^;L2HF(  (J=21B188 ."= uVPh!@G"/wIIOUUPPQ(@JIK2PX@.~_K]KK_ L@+~ c_K]KLY@%$#"!  (( +"&'532655##57546632&&#"3#3(  KRR/W;+H&)2Hh!@H((FM  m &"pVP-1,0;1KPX@ 'JKPX@ ' J@ ' JYYKPX@6g  _ K ]K _K_LKPX@4g  _ K]K _K_L@6egK  _ K _K_LYY@!21641;2;,*"  00 +2373!#"&'532655##"&'53255467##"&546"326554&e9 ~HF(  :c/dqsN1ampik976,PFYVPh!=uzw*| %+&yAQXLNn"u@ JK2PX@$~KKK`L@!~dKKLY@""%# +3667733#"&'532655#'# ٕSHF)  2@=*ȭVPh!@37`@  JK2PX@~KK_L@~cKLY@ %# +3#"&'532655#2HF(  KuVPh!@N,2@J IKPX@-  ~_ K ]K_ LK2PX@1  ~K_ K ]K_ L@.  ~ cK_ K ]LYY@/.+)'&$" 22 +"&'532655#4#"#4#"#336632366323/(  KR;2R>/rW/31,Gl#|VPh!7+*&G!0wIIOUUP7,#KPX@ J@ JYKPX@$~_KK_LK2PX@(~K_KK_L@%~cK_KLYY@ ## +2&&#"3#"&'532655#3366   &F+2HF(  KqT,<4VPh!@"\*<-,9y@)("JK2PX@ _K_K_L@c_K_LY@-+&$99 +2&&#"#"&'532655#"&'532654&&'.5463\1-(H%B10/D%)HF)  "9R),f'+&254A v,k$ )>0E+rVPh!;{+=.LL.@%$JKPX@"_K]K_LK2PX@*e_K_K_L@%eW_K_LYY@)'"  .. +2&&#"!#"&'532655##"&'5326546, HF(   K@/X r/VPh!UP2R1r [S9"l@JK2PX@~KK`L@~dKLY@  +"&'532655#3366733u(  Мi  iqHh!@"<;7KVP5"m@  JK2PX@ ~KK_L@~cKLY@%# +3#"&'532655#'#375q:HF)  ssjk"VPh!@ "m@  JK2PX@ ]K]K_L@c]K]LY@%# +3#"&'532655!5#5HF)  "aVPh!@XXr*-*5KPX@()J@()JYKPX@+  g_K _K` LK2PX@6  ~  g_KK _K` L@3  ~  g d_KK _LYY@,+1/+5,5&$!  ** +"&55#'##"&5467754&#"'6632332672655P>K#NDI`zz_-((L&1+l:nu2  $0B:H8(JRJJ,(TYWR+(e_b h I94-0'"-,!.KPX@J@JYKPX@$ _ K_K`LK2PX@,K _ KK_K`L@)dK _ KK_LYY@#")'".#. !! +237333267#"&55#'##"&546"326554&;L ~2  $1>K(J;[st1883=41,."FK h JRJG"/ySRTOJJOU-1>c@` !./J_K_K _K_L32:82>3>,*%# 11 +"&55467##"&5463230&&554632&&#"326726754&#"<\JJ;[st^;LXU, 0=21B188`P%2"/."$2[S rw r]IIOUUPPQ-g,#*@!JK2PX@)e _K_K_L@&ec _K_LY@%$('$*%* #" +"&&546632!32673267#"&55"3&&ER~HAtMqG?4W.  $1>K!(,83 ={__@wH?H h JRD8;1B&g,6@ -45JK2PX@(e_K_K_L@%ec_K_LY@20+)%#" 66 +"&55#"&54675&&546632&&#"33#"32673267>K-~I<53@lB9r*.$M2mAFKRMBK"c8=T:7JQ4;'](,/oM;g?<1#8!9x\+  $JR#Ag!h@21: 1)-M/: h +,$+@"#JK2PX@*e_K _K` L@'e d_K _LY@&%)(%+&+  $$ +"&5#"&55!&&#"5663233267267#>Kfq`G?5V.(Y?MyJz  $G+:2JR"qqwH?Hs6mS h F8;1BHw @ JK2PX@)~_KKK`L@&~d_KKLY@      +2#"&54633267#"&55#!00!"//l2  $1>KK*) )*K h JRJ",&w@$# JK2PX@ _K_K_L@c_K_LY@! && +2#"&'3267#"&5532654&#"'66yz    $1>K#F/7CE:9* Y,8 h JRRQRPsO%n@JK2PX@~_K`L@~d_LY@ %% +2&&#"3267#"&55326546, ;J  $1>KX r_Cd 9 h JR [SK"#KPX@  J@  JYKPX@K`K`LK2PX@"KK`K`L@dKK`LYY@###$$# +33267#"&55#'##"&533265C2  $1>K([3Xj*.D2"K h JRJF*&_id;;]W&"(@&'JK2PX@(~]K_K_L@%~c]K_LY@$" (( +"&5532654&##57#5!#"&'3267>K"c8=TGOTĥgO9x\+  $JR#!SyrayUA/P/: h 3~mG")&f 3+:mGF)&f 3+PmG%)&f 3+uG)&f 3+PmG&)&f 3+ GI)&f 3+gG,)&f 3+imG.)&f 3+1xgG2)&f 3+G5)&f 3+3gG6)&f 3+ gG7)&f 3+ gGg)&f 3+Gj)&f 3+3G:)&f 3+$Gq)&f 3+3(gGl)&f 3+3NmG>)&f 3+1LgG=)&f 3+zmG?)&f 3+3mG@)&f 3+3gGA)&f 3+umGB)&f 3+GE)&f 3+*mGO)&f 3+GP)&f 3+G)&f 3+gGV)&f 3+gGW)&f 3+1wgG)&f 3+1mGX)&f 3+rgGY)&f 3+*gG])&f 3+igG])&f 3+vgG^)&f 3+`gG_)&f 3+tG)&f 3+Zk&%N3+NL&EN Z.k&% N.L&E ZRk&%L 3+NTL&ELw 3+:Z&&'zv3+-&F'zvZ&'N3+-+&GNZ.&' -.+&G eZQ&'L 3+-Q+&GLm 3+Z'7@4J]K]K_L!,!&%" +#"&'532654&'7##324&##32AV#)$-'p[1DhcQAz8>R KPr& -vp/-+*7KPX@ ) J@ ) JYKPX@'K_K _K_L@+K_KK _K_LY@,+31+7,7$"** +"&546323&&553#'##"&'532654&'7726754&#"[st^;Lr1BU#)$-.=21B188 ."= G= -%8>R AwIIOUUPPQZ8&' X-8+&G -Z+&(/3+-$q&H&Z+&(+3+-$q&H%Z8&( /-8$,&H (!1&(--$,&HQ5 а3+Z&('zMH3+-$&H&MCzZ&)N3+&IN3+:m&*L3+-+&JLmZ&+N3+LF&KN$ְ3+Z.&+ N.F&K Z&+jO3+F&Kjkְ3+>&+zP2F&KzDZ(&+ N(F&K I1&, 1e&LQ ԰3+ &,3+Vq&*Z&.v3+El&Nvְ3+Z.&. N.l&N nZM&. \NQl&NL 3+Z.&/ lG.&O .m&/' lL3+.?&O' Lְ3+ZW&/Le 3+W;&OL 3+Z8&/ 4/n&OJ Ѱ3+ZU&0N`3+N&PN~Z.U&0  N.,&P &Z&1N 3+NF&QNZ.&1 N.F,&Q ZH&1L 3+NHF,&QL 3+Z8&1 N8F,&Q I:&23+->q&R6:&23+->^&R6:+&23+->q&R+:+&23+->q&R4ZG&3v3+NL&SvZG&3N3+NL&SNZ&5N3+N&UNZ.&5 J.,&U Z.m&5'L 3+J.&U&L1 ZR&5L 3+ T,&UL 3+.&6N3+-&VN..&6 D-.,&V 1.&63+-&V.&63+-^&V..&6'N D3+-.&V'N 1/&7N3+c&WNMkk3+./&7 Z.&W )]/&7LQ 3+M&W 8/&7 ",&WJ ΰ3+U&8jJ3+KC&XjU&8Q3+KC&XQVU8&8 xK(C"&XJN ʰ3+U&8z3+KCq&XIU&8z3+KC^&XI&9QS3+9&YQ&.&9 {.9"&Y T&:Nm3+ N&ZN5.&:  .N"&Z &;N3+=&[N&;j3+=&[jp&<N3+9&\N+&=J,3+&]J.+&= j."&] 0M+&= "M"&] NMF&K Ih&Wjxx3+ NE&ZO 9E&\O}*'&DN&@N3+-q&}-q&}&-q&}#-q&}$-q&}-q&} --q\&}-q\&} &$ù 3+&$& 3+X'$ ̰3+Q'${ ̰3+8'$e ̰3+=' {$ ̰3+#*'{$q ΰ3++*&$y { ΰ3+&&&&&&&&&&&&& '^&(i칻 3+^&(i& 3+'({ ̰3+'( { ̰3+'(] ̰3+'( q ̰3+NF&NF&&NF&7NF&8NF&-NF& ANF\&/NF\& ' &+f칻 3+&+d& 3+'+{ ̰3+'+{ ̰3+'+{ ̰3+'+ q ̰3+*'+q ΰ3+*'+ q ΰ3+N&N&& & &&z& \&|\& t',칻 3+',& 3+',>{ ̰3+',4{ ̰3+',Z{ ̰3+',D { ̰3+*', q ΰ3+*', q ΰ3+->&R->&R&->&R->&R->&R->&R #)&2G칻 3+8&2V& 3+'2{ ̰3+'2{ ̰3+ '2h ̰3+'2 { ̰3+FP&FP&&FP&FP& FP&FP& )FP\&FP\& &&< 3+'{<@ ̰3+' {<_ ̰3+*& <N ΰ3+5*&)5*&&(5*&5*&5*&5*& 5*\&5*\& A&uJ칻 3+Q&uZ& 3+'u{ ̰3+'u{ ̰3+'u^ ̰3+'u { ̰3+*'uq ΰ3+*'u ΰ3+-q&}-q&}%3&&&&%-NF&"NF&%G%&oN&%->&R->&R%)FP& FP&%/5*&5*&%-q&}'-q&}'&-q&}&#-q&}&$-q&}&-q&}& --q\&}&-q\&}& 4&$ '칻 3+#&&&$ 3+'{'$> ̰3+'{'$B ̰3+']'$& ̰3+' {'$1 ̰3+*'{'$ ΰ3+*' {&$x ΰ3+NF&'|NF&'&|NF&&7|NF&&8|NF&&-|NF&& A|NF\&&/|NF\&& '|&+g&칻d 3+&+b&&_ 3+'+'{ ̰3+'+'{ ̰3+'+"'{ ̰3+'+' q ̰3+p*'+'q ΰ3+m*'+' q ΰ3+5*&')5*&'&(5*&'5*&'5*&'5*&' 5*\&'5*\&' &uV&칻h 3+&u`'r& 3+'u '{ ̰3+'u '{ ̰3+j'u'[ ̰3+~'u' { ̰3+I*'u'q ΰ3+I*'u' q ΰ3+-q&}M[-q&}Ls-q&}&-q+&}-q&}&%3-q&}QM-q&}&QM&$Mt3+m&$L3+&$I 3+&$%' 3+4&$GS2dD@'JW`P'+D5665&&54632G "" !$?S*,"3D`dD@ JK PX@pU_O@~U_OY@ %#+D3267#"&55K  (/742R48PGSe]Q=pW`!-QdD@Fg h W _  O#")'"-#-!!"""" +D663232673#"&&#""&546323"&54632p62 2*=442+""$$##$$1B1BNF&&"|NF,&|NF&&%G|NF&QaNF&&Qa|U&(`1 ̰3+S&(^% ̰3+ &+i; ̰3+&+^% ̰3+Z&+TdDKPX@ JKPX@ J@ JYYKPX@g_OKPX@Ug_O@Ug]MYY@#+D5665&546327.'534 #C'!  T*0(+A65 %U TdDKPX@ JKPX@ J@ JYYKPX@g_OKPX@Ug_O@Ug]MYY@#+D5665&546327566734 #CN  "'T*0(+A U% 66vF\$ϱdDK PX@1p ng h X `   PKPX@2~ ng h X `   P@3~|g h X `   PYY@$$ """" +D663232673#"&&#"565&&54632v62 2*=442+8751B1B'#%8&M&L &z &y&Q`&&,M3+hm&,L3+',1 ̰3+',% ̰3+TdDKPX@ JKPX@ J@ JYYKPX@g_OKPX@Ug_O@Ug]MYY@ $+D&&54632.'53?C# 4n'!  TA+(0 65 %U TdDKPX@ JKPX@ J@ JYYKPX@g_OKPX@Ug_O@Ug]MYY@ $+D&&5463256673?C# 4  !'TA+(0 U% 56vF\$dDK PX@1 p  |g h  W ` P@2~  |g h  W ` PY@$#"!"""" +D663232673#"&&#"&&54632v62 2*=442+@571B1B8%#FP&MWFP&LoFP &FP &;=&;=&&FP&QIFP`&p&<MS3+pm&<Lj3+'<1 ̰3++'<% ˰3+&3c& 3+[c "`dD@  JK"PX@UW_O@We_OY@ $$$&+D#.'53%4632#"&%4632#"&o@&" x #$$#"#$$#j66 %U." "! !" "! [c "wdD@ JK"PX@UW_O@We_OY@ ""    +D56673"&54632!"&54632 x "&##$$##$$j U% 66 !" "! !" "! ^a 'dD@ JU]M+D#.'53aE'#  ^66 %U5*&'5*"&5*&'%5*&Q5*&'Q=&2[; ̰3+&2,% ̰3+^&ug1 ̰3+7&u@% ̰3+&u^ -dD@"JU]M +D56673  "'^ U% 66MS,dD@! JW`P$+D&&54632E?$! "" SD3",{t@U]M +3*{m!@  Ht +'7'77'>RRSSRR>>RQSSQR>d{ 4@1JHU]M  +3'7'7#@ll@y=kk=H+{ 4@1JHU]M  +#'73yAmmA=kk=!($@U]M +5!($pp\'_~_ $@!]L    +#&&'7##&&'7k/[k/4;7~5 4;7~5 {Z$@!U]M +3#迅'H,{Z$@!U]M +#53'!{t&@#U]M +#53#__b{t 0@-eU]M  +#53#3#__b'&{t 0@-eU]M  +#535#53#__b&'. /@,]L   +3!333聈恈}Zq9 #/K#PX@+ g_K _K_ LK)PX@( g c_K _LK2PX@& g g c_L@,g g gW_ OYYY@#%$ +)$/%/##    +"&54632"&54632"&54632"&54632(--('//'(--('//'(--('//'(--('//C'')%%)''''(&&('''')%%)''''(&&(''{t5@2eU]M +#535#53#3#______b&''&{t 2@/eU]M  +#53#35#__bb{u%@"JU]M +'3``}{u@Ht +#7#`uu`b{u @ Ht +'77'`uu`>>>sYkkY777{t 3@0eU]M  +#535#533#_____b&'&gV 1@.gW_O      +"&54632'254#"RVPXTWRX//.wjjuujjwe{zz{fU'J@G JggW_O#!''  +2&#"36632#"&54>"32654&$ 6; .%;DWJM_4[ !U\ 6"H@AUdb/XG)!/# bU'J@G  JggW_O#!''  +2#"&'532667##"&546"32654&L`4[E % 6; .%:EWP  Uea/XG)\ 5#GAAUW"  !/XFD)&f 3+dFH)&f 3+uFR)&f 3+tF[)&f 3+cF))&f 3+%P@MJe g_ K]L  +2&&#"5!#3#3!5"465N,1g8($y s OFpIpVr$F$-4@/+& !JKPX@!  a]K`L@h  a]LY@%%%-%-*($$ +7&'#7&&546677373&&'667'&&##'5%!IMJ@|ZI%"I 0OB$KS T R"oD14:O Zr(jXY LHQc x|{ OkEOcG-G$',K"PX@"! J@"! JYK"PX@W_K_L@g_K_LY@&$,, +2&&#"336632&#"667#"&&5466_3f/1%L$ST24\2( #.5-]6i?Gvq[v8I$,z/>^ {Zmm`N&KPX@ %"J@ %"JYK PX@! n_ KLKPX@ _ KL@$ K_ KLYY@$#! && +2#4#"#5#54#"#336632736]_R;2KdR>/rW/e/Md8!,_i?vTO3x5v]W"F*&7y  2#'+]@Z( Jf   eK  L+*'&%$#"!  +35#535#53533533#3##'#3'#3'#3'#3'#D::::N[o9999PX B..CFJHJJHJ`HHH[Kt >@/ . JKPX@, e ] K_ K ]L@0 e ] K_ KK _LY@#31,*>>   +2####32654&2&&#"#"&'532654&&'&&546uo:-t,!#4-0+M)$ :5 (&%7c`0E"#Q# (*>:cdmIX|213+"k&(=0SY{ F?LQ "&*.14h@e"J  f   eK L4310.-,+*)('&%$#!  +3'#53'#53'33733733#3##'#3'37#3'#37#7#7#)VJ >2)q&\+*]%q)3? KW)-\,P - D@ &. E B JHJJHJ\HHHHHddd<8@5JIfK L +3#533333##H@@ ƚw*/a::a/*(6@3J]KL +35'75'75#5!#77U)~T*~[*Z*z:=VY:=V~~a?=[Y>=Z/<@:*JKPX@7  g_KK` K _ K L@4  g_KK^ K _K LY@10750<1<//(&!%&! +33326654&&#"'6632#6632#"&'#2654&#"tZOm95_?+[$-&y=rRft;Rf[[R%SF"3  "2 "*  $"WNS8U/pN]ceX[F-X:E-@6."&15 +&2C@@!  J_KK_L.,&& +"'532654&''#7&&5466326654&#"r%! kR4hP=592V5UZ12=`O- s .c@eb^@EW)`X6`V&ZLVXl#W%%#M:4 2#,2i@feg ]K ] KL%$ 1/.-'&$,%,"!# #  +23#3#####535#535#3&#364544#326er5,-;v99995')9UME  EG\cE;Ex**o;  y+:%N@K %"JIe_KK]L!  +5&&546753&&'3#667]W8k,2 Q,/e<@G?H< PH *$yGZ~w $D@A  fe KL$#"! +3#3##'##7#537#533.#3[u]DNGHMC\t[S D 7rJHJJHJ 3563H 13^@[0 1 Je   e_K _ L.,('&%"!  33 +"&547#53667#5!654&#"'66323#3!3267'zy1W2N/,)P2-4q?h{3]< 446h4,o l_J$J' $ve`J!J %)~:Z#4@1#  JK]L +&&'667#5.546675+T'1; E&#C%Wd>C^BE@G&{ %IG]idb &}adyAD@AJ~ eU]M"" +353267#53&&##5!#3#<5H 82OÝ# qo _I:J/*J&3JJ&3JJSh pp3+1$/7X@U ~gge W _ O%%7520%/%/.,(&$$  +".54>32'26654.#"'32##532654##Pc67dNLe96cPRP-Pm?VNM/RLV>RF#+OE 6cPLe96cPPc6@NY?nT/NYYNTEDCL#'F :@+ * JK PX@9~  ~ e  g  W _ OK PX@2~ e  g  W _  O@9~  ~ e  g  W _ OYY@ /-(&::   +#'##3#3'&&'2&&#"#"&'532654&'.546hcoazm6uu):#4 !.2LG<3" 0 FrJJX6S  R J  ++38 O   ) .8" .@+eU]M +3535#5353ԕppC9@  * )3JKPX@*  hg ]K_  L@.  hg ]K K_ LY@".,'%!99 +3354667'73"'53254&##532654&#"'6632ut}&5]G> A#F"/7-3)1J2=P',2/V6 *'>sT"]4 N!E=4"1 8#;D iC.KPX@#    3 = J4I@#    3 = J4IYKPX@2  h  e  g_K_ LKPX@6  h  e  gK_K_ L@:  h  e  gK_K K_LYY@$861/+)(&#!CC$' +576654&#"'663233"'53254&##532654&#"'6632m-!'1<P5AO3:3utxG> A#F"/7-3)1J2=P',2/VRk+0+J#?;-J5.b6"]4 N!E=4"1 8#;D,$<@9e eK ^  L +35#535#53533#3#!ZZZZZ"VJTTJVa}15@2e eK  L +35#535#5333#3#NNNNNNNNNTLTTLTB@?Jgg K^L"" +3273#"&'!!&#"#6632 $ IF3 [ %IE4 5JL}G5JL! GkKPX@%g]K]K L@#eg]K LY@%! +3#53532##32654##3#ZPP4yhA2@KxErra}lCqCf6@rAaZ#N@KJe]KK_L##  +2##3267#"&5#32654&*%=#ҨQ /R].1KAFjl1I3r R^ |213+*0$*0K"PX@ " .-'J@ " .-'JYK"PX@#VbK_KL@$faK_KLY@ 5 +#7&&54677'6632373#'#4'76657M,ASpq&J%1+l:-M/CGh8)q%8!&3URTRoe\KJ"'r%SW6..#} '0!P@M Ja ]K ]K_L!!1 +#7&&5#57733733#3267#17M.+5GR+_D0M0 H .G*,PL?2stp o Z05N<6@3JaK_KL"' +366323#5#4#"#R2XlQ`XC3)I*&_i?v]WZ0/@, JaKL +%#5##3773$@<-.TN<l3@0JaKKL +%#5#'#3366773l&@ ٕm3=*0+ 5@2J]K]L  +5!5!5!!V_b}b<" 5@2J]K]L  +5!5#5!3DXXra: KPX@  J@  JYKPX@_K_LKPX@K_K_L@!K_KK_LYY@    +2373#'##"&&5466"32554&LH`}\IN{GH|wFVXGJ2%L6N%3SxyS|wztenZ&e3xKPX@ ,!J@ ,!JYKPX@~KL@~KKLY@'& 33 +2&&#"#.'#3>73>766$  va  `[  hh  @Fx *- w ,4..3- zFFEApAFEE@K v,5mKPX@ .!J H@ .!JYKPX@]KL@K_KLY@55$- +333>733>776632&#"#'.'#>  C@  EF$  ]*,"EA/2(>@7=yFQn,8FO@ @PF 9,'p@$ JKPX@g_KL@gK_KLY@ ' ' +23673#'#5267&&546"654?B.+ iЙb6  P>&,D<4J28977S 0?DY/0,Z #@ eKL +33!!Z~N"#@ eKL +3##Е"o"--"0@- JH_KL  +"&546754632'6654&&#">2l&*M7nUm~X)DQ'" U=F4fAMI `c{]HvcK+H+'/JB0+7'%'%4$$$$5555(}+,@)W_O +##"&54632+]'#$$#K(&h^ #@ J GW_O$"+#"&54632'7#$$#B"/B(^s^ "@gU]M$"+#"&54632!5! #$$#fK"](S2FK PX@nU^N@U^NY@ +5353(5S5qFH@t+##5#LF:z@t+'3533L:?He$@!W_O$#+#34632#"&Z)))) X&%%# ?Ro &@#~W_O$"+#"&546323#))))sZ,%%# ?zV V3+( 0+5''5'(f5a ::6K12 "F ]][^q [JK"PX@]L@U^NY@    +566735!`6:=K F" 21]]JWr(h JK PX@ _L@ _LY@$"(( +&&'536673"&546323"&54632C?E9:EA""$$##$$"@ $$ B"[WWXK PX@e_L@e_LY@  +!52#"&54632#"&546B$$""$$##W]]S^W;@8e d_L  +5!663232673#"&&#"K301(=220*]]1B1B[WWJK PX@e_L@e_LY@  +!52#"&546$$##W]][0@-eW_O  +!52#"&546$$##]]M #/\@YJ  h  _ 8L%$ +)$/%/##   +56673"&'332673"&546323"&54632 l9VUI8+)9K[##$$""$$Y 5 :ZK*),'I\M #/@ JK PX@*  nh _  8L@)  h _  8LY@&%$ +)$/%/##   +#&&'5#"&'332672#"&54632#"&546 @9%[SVUI8+)9$$##$$""5 : II\ZK*),'*Mu %JK PX@$n f_  8L@# f_  8LY@" !%%  +#5667!52#"&54632#"&546F8@ B$$##$$"" : 5]]|*Mu %O@LJ f  _8L !%%  +&&'535!"&546323"&546329l K##$$""$$^: 5 y]]$D'KPX@ JKPX@ J@ JYYKPX@ W g c8LKPX@!g g c8L@(~g e c8LYY@%$" ''$ +&&5463256673"&'332673?C" 4  "&OUPM ++,,KSA+(0 U% 56H;;H$Dz'KPX@ JKPX@ J@ JYYKPX@ W g c8LKPX@!g g c8L@(~g e c8LYY@%$" ''$ +&&54632.'53"&'332673?C# 4n'!  UPM ++,,KSA+(0 65 %U H;;H$D'KPX@ JKPX@ J@ JYYKPX@!W  g c8LKPX@"g  g c8L@) ~g e c8LYY@%$" ''# +5665&54632756673"&'332673M4 #CN  "'NUPM ++,,KS*0(+A U% 66H;;HDr'KPX@ JKPX@ J@ JYYKPX@!W  g c8LKPX@"g  g c8L@) ~g e c8LYY@%$" ''# +5665&546327.'53"&'332673-4 #C'!  UPM ++,,KS*0(+A65 %U H;;H"KPX@J@JYKPX@]&K]'L@]&K'K_.LY@ ""+"'53267>7!3##'#P'!  H񭦦u  +K |=T gp.loc&>X.l"KPX@ J@ JYKPX@](K]'L@](K'K_.LY@ +"'532>7!73#'#'#U4! Ljkssfn +M w $^黻YZc:@7 Jg]&K'L#!+33273###32654##Z| k dEA2@KxE`V8z39hNX,(|@ JKPX@](K _'K*L@'(K_/K'K _.K*LY@#!((#$ +33663273#'#"&'#02654#"NyJ;HgfmkJ;Fm31f:0/G!0YW\^+& _UPIIOU>J@GJe e ]&K] 'L' +#.5463!!3#!!#35#":&j^GK;@>: /O:ci||}*1/7^,!(1KPX@J@JYKPX@*e   e _(K_ .LKPX@8e   e _/K ](K'K_ .L@6e   e_/K ](K'K_ .LYY@!*)-+)1*1'%#" !! +"&'##7&&546336632!32673&&#"35#"lR{*A|aK%Af:G?4W.)X34,8Sf(&6 ilMCRW(:nPH?HsY1B8['"'Z*@'  J H&K'L+!##37'773'_HS8sIgGjdCVLxCk^Nk2)@&  JH(K'L+773'##37D6 mRDJ/ߕw@9)V@M9")8KPX@-! J@-! JYKPX@)g]&K_'K_ *LK2PX@-g]&K'K_.K_ *L@*g c]&K'K_.LYY@1.,+%#88 +"&'532654.#"###"'53267>7!6632 6F">#HK-GQ$!  +K<'!  "A6o_:Kx iQAM' L.loc&>X. |=T g!L^iH I",KPX@"J@"JYKPX@)g](K_'K_ *L@-g](K'K_.K_ *LY@&#!  ,, +"&'532654&#####"'532>7!6632X >:2DCGt +M?4!   EtGBm  GRCRYw $^?|]az;ZO){@JK2PX@'eg &K'K_*L@$egc &K'LY@)(&%'1 +6632#"&'532654.#"#!#3!3"A6o_:KxF6F">#HK-GQ$! !L^iH iQAM' 4N o"%T@Q Je  g(K'K_ *L %% +"&'532654&###5##33536632~ >:2DBGЕЕ  EtGBm  GRCR"?|]az;Z0! *@'a]&K'L +5#!#!35LN<" *@'a](K'L +%#5###!ĆƕmN"KZ058@5 Jga&K'L##+5#54&#"#36632309*T4?i5dq44aZN<6@3Ja_/K]'L'"+5#4#"#3366323FXC3R2Xl?v]W)B*&_iU` S JKPX@o]&L@U]MY@ +#'##'##'5(KK'+T2222T+$>@; J~KL  +"&'575575377>532aaaa?G$Q 2!W!>!W!z6W6>6V6 ?cBEf<Z: *@'K^L   +!3!!3" }6Z.U 6@3JdKL %# +#"&'53267467####33UpZ++' Ω6mev+2P9q30jz"U&KPX@ J@ JYKPX@~_K_L@#~_KK_LY@"! && +2#"&'532654&##57&&#"#466{zoRa6Z('W%G>EP+q>/JCIl[mbYd{:/.4it"NSLYy>$ ʰ3+:&L@JHK#PX@_K_L@g_LY&%%' +326654&#"56632#".5466=yR_*_K1?E3 ' 3#Di;BiAu[4Du93`oGit-L,EEg 9mNQR+U|Qgm  5@2 J~K`L  +"&5466733>773'3267IN.W>䠘c@Xq97O FB(M: ,- -* Eb4:?2FJ#E@Bgg]K_ L##  +#532654##532#532654##532|2;]DQX[*[W .;T/9UN$R5.%M`NE-I,k5"*C`PA'C)1%@"c]L  +"&&54633#"33Sf<ziXGBZI=e>iw~>7?IEZ.>@;JecKL  +"&'532665!#3!3,#*嗗9f~75d\q3Q&7) 3+'C I@F J~_K_L   +"&5467'572&&##"3267Rg\D_M)61\/e7-, %2_9 t)W  ~"5iz| wmlFB8 ( &Y. =>&$$`*@ JKPX@! f_K_LKPX@% f_KK_L@) fK_KK_LYY@)'#!&# +7#36632#"&/.'%32654&#"42'mtIItv$#43ZV_aTT``V͏GP[oo\`T46;5 =ppp"dJKPX@fK_L@fKK_LY@  +"&''##3326533'.'m4 6/JCA4 \L !1NS2JwE346;5 1@.JfKL +>73#'!#3'.'M4443! :@A; 6\46;5  "7@4JfKL"!  +1333##3'.'>77#T_U_p p+6+0046;5 ,75GD  +H@E&JIfKK_L!!!+!+%# +!#"&'532677'!#3>73'.'HoP ?9,- 4443Gl= )+T :@A; _46;5 #C&hy83+4@1 JeKL +53533#773##DBB<@ |BB|Tr-. Z'@$  JKL +%7'#37737#'`H@@;g e ]KL%! +75332##3##5#32654D4yhAXXE2@KJ|wh?lB8|JJ39h$pK PX@#pg ]KL@$~g ]KLY@!$$  +2###5#"#&&546633#326544yhA v#RDE2@Kwh?lB!.M/P|39hq"*KPX@  JKPX@  J@  JYYKPX@ g _KLKPX@( g_K _KL@& g_K ]KLYY@$#'%#*$*!  "" +%"&554#"566323332###5#32654]wx+ ,UK3:4yhAE2@Kv*<r S[,D;Pwh?lBP39h:H&8@5JG_K_L$%&" +7'#"&&5466327#'32654&#"lX+ tIIutIVZ$dNsV_aTT``Va#4\oo[[ox(4W(W .ppp:)'3A@>JGg_K_L$%&% +76654H#''7'#"&&54663232654&#"VZ-# &-> ::au$n@ tIIutIV_aTT``Vfx(!9!,D'?#@R%lK9FN\oo[[oppp(b)@&Je]KL$!  +32##532654&##(В%=#ҨQ1KAFI.jl1I3{213+9$;@8Je_K]L'&( +!#5!57>54&#"'>323533#lb*4;"R;O7[g =+L֓JJS+8.!a'RP,HG*JuXKPX@ J@ JYKPX@KL@KKKLY +3>73#'#73=Hw**EKQ7 ;AA; 6|38@5-"JIKK`L%" +%#"&'532677.'#3>73>73$)y99,- a  `[  hh  [K )+w ,4..3- zFFEApAFEEGI@Fe   g eKL  +2####53533#2654&##H{2udKXXoo1FF>B=n`7c>P1c66c;262+G=@:  g eeKL! +73##5#53332#'32654&##ooXXW{2udK1FF>B=3c>>c)Pp]9c=p18/- $@!  JKL +!57'5!6673WWWEW9Ĭ+r(VV((VV(B@7h3C+.*?@<%$ Jg_K_L%%!$%) +#"&'532654&##5326654&#"'6632U@PV}xBe&"^&F@\N2-?F10)H1,nKbn#GX  YH^w723/w)%+ e$*dp*>@;Jg_K_L! '% *!*%$$$ +3546632###"&'5326655#%2654&#"6jNmmq;9fC,#*i,2(" /5lRlaR\q3~84Sw)+ (309-Q">@;  Jg_K_L "" +"3267#"&54632#526654&01$&>5\mO~KJ]j-:YB;4< l vlrBigv=fahQK2PX@]K_L@g_LY@  +#"&&5467#52654&#"rHIttI*/aTT``VV\no\\oEz2}pppp[1{KPXJ@ JYKPX@!e_K_L@e_K]LY@  +2&&#"3##336608&E+q^<4Y|H\*<92*.@+$ J]K_L**!% +#"&&5467&&5467#5!#"2654&'z_YzEpBaN($~Ɩ'!.4,(5#<3xMiy1_GNa1*xx "420<!6%3692k ʰ3+"/5 ʰ3+Z1 !g@JKPX@!_K_K_L@_K_K]LY@ $%%" +%3267#"&54&#"#3366320\J2A?Jr%j?sy r`P.AH5V/F*&u[1gKPXJ@ JYKPX@_K_L@_K]LY@  +2&&#"#336608&E+q^<4s\*<7R1@.J]K_L%%! +5!#"3267#"&&54677h^z<_T+X3/\9eL[BL~~HzKajP]i'Z @fKL +!#!3!3N4Z0='@$ JaKL +!###33&&'33# 6j1b2RZ!E@B  Je_K_L!!%"%# +53>32&&#"3#3267#"&&'@ Sb5k11(Q'KY UP+X3/\9cK #|\N{aV|T[J\'D@A'&% Je_K_L%'#& +32675#5!#"&5576632&&#"%&RB ,8zL7A9n-2!T.Bb Fl=w~Y |y=6?Y'@$  JKL +5737737##W<ͬ@Y ^T!Y-.),@) JKL +73737##7'3&&'WVVWTWsS\ b Y 3  (O( @@=  Je]KL+% +!#'##575327'7&&##267cWW(SJA2B5.1@A Y Y ?`$+6$.6@3 .-   J_K_L$-%& +7&&54632&&#"7#"'532654&&'&&'Yp8d811N)+.00w'+~qY3m68/%>(  :&`kv( ("YL9_q+%+!&! \K PX@!pe]KL@"~e]KLY@ &! +!#!##"#&&546633!3 v#RD4N!.M/.]:#3KPX@ J@ JYKPX@ g_K_L@$gK_K_LY@%$-+$3%3 ## +"&'532655467##"&&546632373266554&#"YFx9zNc`G]}?HV/@18H"QL4G$ C3EN,)/ZakR'Li5X4te8c?>b7Wv JKPX@& gK_K ^L@$g gK ^LY@$! +%!#"&54632533#54#"3WG#F?<5gg+#}}6=/2=M3 >. ʰ3+/7C ʰ3+%S4@1JGgdL##$) +&'#"&5463233267&#" )IF/CXL5 !!("1>! @==< % $KPX@"!J@"!JYKPX@_K`L@K_K`LY@ $$ +233267#"&''#'&&#"5666?)7w% $NWBY% #-%J71<({ WV8+{ Zk$;@8Je]K]KL$#"$!,  +32###32654&##32654&#Zގ95#;"ytXB3Z&1 :|" /@,e]K]L  +3535#535#5!:̾B^]z]N"*",->-,)0KPX@  J@  JYK PX@( pe _K`LKPX@) ~e _K`L@3 ~e _K_K`LYY@+*.-*0+0))$"&$& +%#"&'#"&&546632!326732654&'%"3&&@3"-%K9R~HAtMqG?4X.#,83"%A*={__@wH?H!  8;1B&,&,9[@X76  "!Jgg_K_L42.,+)&$  99 +273267#"&'#"'532654##532654&#"'66Gxz !!9#1D- 5$#8!9x\J"c8=T:7JQ4;'](,/o,-0%3.& X7>$ 1)-M/"{#Ag!h+",)-E,$,P@M !  )(Jg_K_L&%%,&, $$ +"&5%&&#"5663273267#"&''265'siD96Z/)[@es !!:"2D8t]5>+ wc84sZ["4/% X7> TJjCM;'N"@KL +3#3㕕"-"&*P"+@(JK`L  +"&'532653"6 *&Uu"1G2R1^*@' eKL +3##53533533###JJJJHaOOOOaH*@'  J_KL%% +7546632&&#"7# W/W:0B#(#f*-Y*FM  m &x1WF1@.  Je_KL"%$ +3546632&&#"3###H/W:0B#(#HCFM  m &e"*R3 )0@-Jg_K_L$&&%%" +#"&&546324&#"663264&#"326RP|GP{G=<=< ;+*8 HC\BdLZVL2%%2-$"FhFM)&f 3+x tKPX@J G@ JYKPX@_K_L@_KK_LY%&$4 +!#'##"&'7326654&#"'6632xqT7   &F+)&H+;W/\*<<48& m  MF1"=@:Je(K`*L +"&'53265#53533#"6 *NNNN&Uu"1 aa2R1'"8@5g(K`*L  +"&5463333#'2655#"5IGEIDERgG.6E"MH[RgG,)&f 3+",3F*)&f 3+Nw"`@  JK2PX@~(K'K`*L@~d(K'LY@ $#+33267#"&55#2  $1>KK"K h JRJ"g ,@)Ue]M +##5#53532a33a::gG4)&f 3+1e"&*Q ԰3+K."&* F$T"C@@ggg_ L""  +#53254&##532#532654##532Q(AHFP!I>&?28=JDG5B`L<"=&6 ,`@>4E+d'%@"c]L  +%"&&54633#"33+Wq8wsO?C>L=4Y9\mw7.8:ANF$G@DJK_K^K_L $$ +"&'532654&#"#3366322#.*C3 Q3Yj#Nu"1o56]W)I*&_ia2R1z2f@c- J~]K `K_L/.,*$" 22 +%267#"&&5#5773!#"'5326654&&##57!4.G*1M-GR+_qXh.@f{]0o.=D"UL:D$m o  NG?2sta Eh?Em?'$:"$<#j'%-#>@; J~_K_L%%# +7'572.##"3267#"&&546V|5#"-_\.R(&&< !#44?GIX!m!& &@2JS["F*b-&3>I@$2#(   JKPX@%   g_ K  _L@)   g_ KK  _LY@!GEA?<:640.+)! && +26632#'##"&'#"&5467754&#"'6667754&#"3265%3265.a9(]2mvh#ND1MPCSdzz_-((L&1+l)5_-(7:H8( 0BQ:H8( 0B-%_bJ,(&'!,TYWR+(e%+( 0'"94-0'"94*-#/:KPX@! J@!  JYKPX@"g_ K _L@7g_ K_ K_K _LY@8620.,(& ## +2632#"&'##"&5467754&#"'6632654&#"3265.u8CiMvD{En#(^CSdzz_-((L&1+l!5<;55<;5:H8( 0B-54B~Z6372TYWR+(eQSSQQQQf0'"94*u-+6KPX@)(JKPX@)(J@)( JYYKPX@"g_ K _LKPX@&gK_ K _L@4gK_ K_KK _LYY@42.,&$! ++ +232653#'##"&'#"&5467754&#"'663265.nv*.D2r[3:W.D2Sdzz_-((L&1+l:H8( 0B-_b;;]WF*&(,&TYWR+(e0'"94*v-%0KPX@JKPX@J@JYYKPX@ g_K_LKPX@$gK_K_L@(gK_KK_LYY@.,(&%%%#$$ +!'##"&5467754&#"'66326673'3265#NDI`zz_-((L&1+l:nu :H8( 0BJ,(TYWR+(e_b:9=0'"94*v-)4KPX@ *JKPX@ *J@ *JYYKPX@ e_K_LKPX@$eK_K_L@(eK_KK_LYY@20%$%)$ +!'##"&5467754&#"'6632373'36677#'3265#NDI`zW-((L&1+l:nunNS J:C=( 0BJ,(TY[Z $e^]sN'99 60"94* v-2=KPX@,+J@,+JYKPX@(g_K_K_L@,gK_K_K_LY@ $#%#%#$$ +!'##"&5467754&#"'66326673#"&'532673265#NDI`zz_-((L&1+l:nu -lJ$ /7 #:H8( 0BJ,(TYWR+(e_b:9=TIv:'0'"94,l8@5 JeKKL +#366773#'##5353} 欝@LLa=*3HaOONl+@(  JKKL +%7'#33667737#' I3@ 9P9Rv5F\9H3=*M>H@K6l"9@6"! JeKKL +%7'##53533#3667737#' I3@LL 9P9Rv5F\9H3HaOOa=*M>H@K6Nx"@JKL +7#㕕11 !@eKL +3##53533#<<<<HaOOa,E@B e _K _L"" +55366323##"&'%"3&&267#UogVU oh 0550245hnuunhqzzq5665:99:-,&2@ JKPX@" g_K _L@, g_K_K _LY@('.,'2(2" &&  +"&&546326632#"&'254&#"2654&#"4LwD|7W!8,JL?1 @v2;55<;55 B[ $XE%G.ItBT? %SQQQQQQS-,&RRyL,(@  JKPX@' e _K _KL@+ eK _K _KLY@%#(($$ +53336632#"&'#3##5"32654LyJ;\rv\;F:0/>31abG!0+*&,aOOVIIOUUP,(4KPX@%-" J@%-" JYK PX@,pg _ K_KLKPX@-~g _ K_KL@1~gK _ K_KLYY@*)1/)4*4$#!(( +2#"&'#&#"#&&5466323366"32654\r?oI"7 v#RDyJ ;0939,XE ,!.K-G!0wII J[n,,9KPX@  *J@  *JYKPX@_K_KL@!K_K_KLY@ $EE$%% +%&&554#"566323336632#""##5&&2632654&#"eV+ ,UK9CyJ;\rMe  / UJ24:1'Sb<r R\]@TG!0\H cNGNI-w,(KPX@  J@  JYKPX@' e _K _KL@+ eK _K _KLY@%#(($& +53547##"&546323733##526754&#"J<\rt]01A54a5))"/."FaOO IIOUUP-,'3@&JIGKPX@*_K_K _KLKPX@'_K_K _KL@'_K_K _KLYY@)(0.(3)3''$) +5'767##"&5463237376654426754&#"3J<\rt]01A54,"/."Fn 3(,CU@2H%[IIOUUP")@&Je]KL$!  +32#'#532654&##b{A*{RS+6&(f"WRCMd'"'&u-#:@7Ja_K]L'&' +#5!576654&#"'>323533#61=4R9J5Uc ;*FJK`1F#a&WG'@@)Dt91@. J]K]L +3'#3336732EQ7PHs iCz'<6:7 N";8@54&JKK`L;:.-! %# +%#"&'532677'.'##33>733>773Oa5& )< 2    ,?  C@ A dl*v0/ 4>;+,=@6"EA/2( *3.AGL ,D@A JeK_K _KL+)#'" +#"&'###53533#366324#"326Lr\;J<<L:\rf:0/>31'-8aOOa7"/IIOUUL ,K@H J eK_K _KL+)$" $' +##5#53336632#"&'#4#"326}<<L:\rr\;Jf:0/>31?aPPa77"/'-,SIIOUUNK"@JKL +#366773㕕  ;7 ,+?@<%$Jg_K_L$-%$!" +%4&##532654&#"'6632#"'53266?QP?=HS7:"D-(`E@;Jg_K_L &$) )$$%# +#"&'53265#53546632##72654&#"?&UF6 *1hQhr}w;;-4%%$.;2R1u"1x4@;  Jg_K_L !! +"3267#"&54632#526654&085/. " 81\m~GYe+;QD:Fv v}orEz{c-c2,KPX@  JK.PX@  J@   JYYKPX@-  ~K _K ^ LK.PX@9  ~K _K ^K ` L@5  ~K _K^K  _ LYY@!! (& ,!, +"&546323&&5533733##7#'#'26754&#"[st^;L27`7u8a8{J=21B188 ."= zrG"/wIIOUUPPQNc ,@)~K^L +33##7#33K`7u8a81 rzNc,," IKPX@7~ ] K _ K^ L@;~ K ] K _ K^ LY@#*)'%!  ,, +23733##7#4#"#4#"#336632366]_27`7u8a8R;2R>/rW/"\-4Tc" L@IJ  ~  e ]K^ L ! +3!23733##7#'#32654&##TawA2Q37`7u8a8]MV+3')d"RS?Ftr/'"'D&0@JKPX@-  ~ _ K_ K`L@1  ~ _ K_ KK`LY@!('-+'0(0"!  && +2####3267#"&&5#577335466254&#"\]q`$.G*1M-GR+_-Z8E#]FXPN o  NG?2st4V5:%$&. ,8@5'J_K]L"!!,",   +2##532654&''7&&5466"6654&BR&*383mXñ@6i%=+P;!/K*8X/[85V4r,).l~!S6+K-e-*->#)@&Hg_L##% +#"&&54667&&'72654&#"-5zLwD=kFDg0iLN,xKPXJ@ JYKPX@_K]KL@ K_K]KLY@  +2&&#"3##3366   &F+qT,<4r\*<.e6" "3+N"@KL +#3㕕N, a@ JKPX@_K_KL@K_K_KLY@ %%$# +%54&#"#3366323267#"&*.D2r[3Xj0\I;;]WF*&_i r`N,`KPXJ@ JYKPX@_KL@K_KLY@  +2&&#"#3366   &F+qT,<4\*<"5@2J]K_L  +"&5467#5!#"3267,u<4PYtH7&F""K xtJgrr^^ADV&C@@ J ggdL$"&&%#$! +7#"&5463233#3267#"&"3354#F?<5bb0\J+#=/2= yM r` 3N<,U JKPX@a_KL@aK_KLY@ $# +!#4&#"#3366323#_*.D2r[3XjP?;;]W"F*&_i,E@B Je_K_L%"%" +5536632&&#"3#3267#"&'Tk8S,#=^;0/H""K9r awmsla=;t}u,%+1KPX@ 0/)(%  J@ 0/)(%  JYKPX@"_K_K_L@&K_K_K_LY@-,'&,1-1&+'+($'# +766323737#"&'53255467##"&'%"7&&265*o_e9 ~JJ:c/dqsN1Si.+[ 5,97 ~PF Y uzw*| %+&oe{2,AQtl+@( JKKL +733667737#'#5KЮ@K <)Y3 ,\@  JKPX@_KL@K_KLY@ $ +73366327#5#5%"7&Kr[3XjHHΕKV;4 F*&_i Y  EAj,oKPX@J H@ JYKPX@_KL@K_KLY$4 +7336632&&#"7#5 WqT7   #@-ĕW \*<2*Y ,,6@3 ,+!   J_K_L%.%% +7&54632&&#"7#"&'532654&&'M#vb3\1-(H%B10Cut9R),f'+&.0! &BLLk$ Y / SY{Nq~:, RN"L" "3+->#+@(JHg_L%%$) +32654&#"56632#"&5461K^4<8RnvwTs<9",@) JK`L +"&5467336673'3267DJh^ţg edi-3GA@?e ..3QY7B+*-&DP-$,&HP. &O NF,&Q W-&LPKC"&XP3&II&I'IL&I'IOm&ILf&ION'KPX@ $%J@ $%JYKPX@"_K]K_L@&_K]KK_LY@"  '' +"&&5#575&&#"#466323#3267e1M-HH7=5DtFX $.G NG?+N75!Na-1p o -Q%KPX@  8 A76B+,JKPX@  8 A76 B+,J@  8 A76 B+,JYYKPX@% _K _K_ LKPX@/ _K _K_K_ L@8 _K _K]K_ K_ LYY@FD<:540.)'$#"!QQ +"&'532654&&'.546323&5466323#3267#"&&5#575&&#"&&#"9R),f'+&154B vb 3eKXy $.G*1M-GG*75#-(H%B10/D%u {,=.LL*G,1p o  NG?+U & k$ )>0SYRI1@. JfLKML +13#'#7'.'ͶϚ''#$I}}u2442uR& AR'&MD$$3+R"&J.$$3+R& >R& @R&L\$$3+RI&P<Ri&O$$3+R&& F A3+3+R&Q6$$3+FpK.PX@' e  e]LK]ML@-p e  e]LK]MLY@ +%##!#3#3!#373a||Fqmrs& AF F"D@AJg]LK]ML!""  +2##2654&##2654&## }v6(0wh1%,/:G3()5DFEM5C7/OZF!v' (/O7@4  J_PK_QL  +"3267#"&&546632&&LBHDJ&J(L[_y:B\+]+,"CcWY_vKYXMo/& A,/"&KM$$3+/O&z/"&JL$$3+/& ?F>F@]LK]ML!#!" +##324##326>ŏ:.UQ,FZ >F 7@4e]LK]ML ! +35#53532#'32654##3#F::ŏ%.UQ:hhqꑉrZ\zqF>"&K9$$3+ >FFF )@&e]LK]ML +!#3#3!F_FpppqF& A:'&M$$3+%"&K$$3+$"&J$$3+F& >F&N$$3+'& @F&L*$$3+FF&PqFF #@ e]LKML +!#3##F]Fpq/(O;@8  Je_PK_QL$%$" +%#"&54632&&#"32675#53(.oA3a%.G&STHK' nniQUblp/('&Mn$$3+/("&JX$$3+/#(O& V/(& ?F=F '@$eLKML  +#5##335=אFF lG;@8   e   eLKML +##5###535335335#l8ɔ77ɕ8Xe::::PPF="&JC$$3+>F &@# JLKML  +357'5!JJ"IIPlNNP& As'&M$$3+"&J$$3+U& >~>&N9$$3+>& @xP2F&[ V&L$$3+>F&P%z&Q$$3+PF(@%JcLL  +"&'532653' &&3Zp-;Qb,Pe"&J$$3+F8F @ JLKML +366773#'#F  ȡ3F$"F#8F& 5FF@LK^ML +3!F+qFF& AwFF&'~N N3+F#F& FF&N 3+G ,@) JLK^ML  +%!5'7537%:_b=wwc9>b_FF&@#JLKML +#4667####33ۄF F=H>HFQFlF#@ JLKML +###33&&'lF5=FZZ(Fl& A?Fl"&Kc$$3+F#lF& \FNlF3@0JdLKML%# +#"&'53267##33&&55lqZ*!)&FXZj "5=FX)Fl&Qj$$3+/oP@_PK_QL$%&# +#"&&54663232654&#"o<ec=>cd/o& @/{.&R003+/o&L003+/or!)<@9%$ JHG_PK_QL&-*# +#"''7&&5466327&#"4'326o<eK6$I#,)>c&@%H#+)U $JB!K?$ZK7/6(wKZJ 8/6'wK 6 cVA* b/o& A6/o%&Qc003+0P%@ #"JKPX@#e _ PK _MLK"PX@.e _ PK ]LK _MLK'PX@+e _ PK]LK _ML@3e _ PK]LK]MK _QLYYY@ %%  +2!#3#3!#"&&5466"3267&&H:j:^|==|`B>>A44PqnrsK[YKtcUUb M FF -@*g]LKML    +2###32654## so+fV2#-8U3F`W3[8F(+IHF '@$ggLKML$"!# +###33232654&##+eW8>ro%07,0053Z7qFWd(,$$/uuP+@(J_PK_QL$%&! +#'#"&&54663232654&#"oCIkc=>cdDJKe$~"*B4RWk"J&& A&"&K$$3+&O&z&"&J$$3+&#O& >RP%K"PX@%  J@%  JYK"PX@~_PK_QL@"~_PKMK_QLY@ #$$$& +#"'532654&##57&&#"#4632>D0dN:21+.-:P &24vivJ MD0R2 y # #]`>@epzWPF!@]LKML +###5ٝFr,rF/@,e]LKML +#3##5#535#5ٝ^^__Frggr"&K$$3+F&z#F& C9F!@LK`QL#$ +#"&53326598pUz74:2FBe:xhnD9C9& @ Cd"&R$$3+C9&Lr$$3+C9F'2@/JcLK`QL#&%" +3267#"&5467#"&5332653 $8B," z74:2%%'(oW>2$@xhnD973>73G  HG  HG H 6::6 F:;GABG;93C& AC"&J$$3+C& >tC& @nDF @ JLKML +%#373#Ǻxuʤ,F#@ JLKML +#537ǏǚtsFh&  A"& J$$3+&  >&  @F /@,J]LK]ML  +35!5!!X}qVq&  A"& K$$3+& N$$3+/GL)&f 3+9: @W_O%" +4632#"&9K6";#L46K`E87.B::2,21@ 13+2G)%@-G3t@ZU0 ʰ3+ e @ J]L +!!57'5!eWWEWWV((VV([(1*@', JKL11 +13>73>73#.'#.'[  hh  [a  `Y  [zFFEApAFEE6w ,4..3- @BFFz5@2Je&K'K`*L%#+3!3#!#"&'5326T_S. =65]T s0$O@L Je Q ] &K ]'L$#+!33##!3#5!#3>7#! _A7&B4 '6  Zj8NJ҄~FG/ &H@E#  J  ~ R]&K^'L%$"! +3667&&53667!3#5!6675#35mGK8 pZA)F(ikhWN= ZF&DRW19z&;/|KPX@ J@ JIYKPX@Q]&K_'L@"a]&K'K_.LY@$(+%#5###"'53267>7!}  +K<'!  }L.loc&>X. |=T g'@#K.PX@JG@JGYK.PX@a]&K]'L@#pb]&K]'LY@ U"%!#+5663232654&&#!5!5!76#"&#"J :6@.5'9:Vofq.gi4`Hp  b}b+M1C\ '@+K.PX@  J G@  J GYK.PX@' e a]&K ]'L@-p e  b]&K ]'LY@*% %!# +5663232654&&#!57#537!5!3#76#"&#"J :6@.5'9:ezmsofq.gi4`Hp  b|}b|+M1C\ (G6'@ '@$ J&K`.L%%+7'5!3267#"&&wWEW$,B'3R/(VV(_ o  NU6@3 Je]&K'L# +53533##54&#"#54675nlCJGHok|II|L_SNGYgK:".@+ J~&K`.L&"+%#"&546733332654&'#55⥯cgc`V_aT05:5hhQrqK4::4'4  6:5S@P& % 3J~_-K_ .L1/*(#! 55 +"&&54632&&#"32675332654&#"'6632#"&'ljA'V52З3EOVJ'& m  MFj8b?ju|,79$ <@9g]&K] 'L ! +3#5!32#!3%32654&##J1c>|(CMOH!L~8b?ju6|,79$Z] =@:e  g&K ^ 'L %! +333533#32###%32654&##Z1c>Ä(CMOH!LLL}I8b?ju|,79$:!KPX@e_-K_'LKPX@#e&K_-K_'L@'e&K_-K'K_.LYY@ $%##+4663233###"&&%4&#"326:DlIdlENUTLLVSNfo[64`O\opppZ:4@1Jf&K 'L +33!3####3'.'Zofeq%3**,,0) *0- 7@4Jf&K]'L +!3'.!'&]  {5[63L .4. CC.4- E@B  J ~e]&K'L  +%##5##7667'5!#7#"!&&#T$JRA{@TJ|a><J;4W\DD\W3.01Z: ?@<J f&K] 'L  +33!3!#3'.'!'Zo&q8:];%3*,,0) *0-  ~`@ JK'PX@]&K_'L@ ]&K'K_.LY@ %'+!#'&&'####"&'532673͙: '9. / .P:6e@W- v0,0G @05@2Q] &K]'L +!3#5!#3>7#!_A7&B4 '6 }1NJ҄~FGU@ JKPX@]&K_'L@]&K'K_.LY@ $(+!###"'53267>7!!  +K<'!  L.loc&>X. |=T g}ZX,@) J]&K'L+!##33!!#4667#Ω0P\$"}R"XO:&2" "3+:'3I@F  g_-K _.L)(/-(3)3#!''  +"&&546632'2654&#"7"&546323"&54632tIIutIItaTT``VV(())(()) \oo[[oo\pppp !##! !##! :' .  .07@4JQ]&K]'L +3!3#5!#3>7#!_A7$A4 '6 NH~gFG.+7@4J_-K_*L+++"&'532654&&'.546632&&#"8`,+b0A?$?(<2@nDJb)1)C)3:!=)3N-$D4)=71A[?Hl<vA3*<4%Q^;}.(7@2 1 JKPX@# g ] &K]'L@+ g&K _ -K'K_.LY@64/-(&$&$ +333####"&'532654&##5326654&#"'6632Gї.Q}.NP"_U|iC`l'7(R0&/*T4!aZ'44 '53@,5<@&JK PX@/Wgc ] &K  ]'L@0 ggc ] &K ]'LY@!<;763210,+*)('$" 55+%2#"&'532654##532654&#"!#3>7!366#!a'C)("$/S[*E>#&6b%#/3!%:7&B4Z> '6 )%"&+? S )A  0NJ҄ FG ;@8Je]&K'K_*L%&!"+%4&####5!#32#"&'53265Y). ֪px#N@4#+#L~~e\2R1u"1/+@(J]&K_.L%$+7#5!#3267#"&&κ+#,Cf9V~~57~3qZ%D@AJe&K^'K]*L %$ +"&5463!#"3326654&#!3!3;55-&&"='00^(((aU7+,3C %!%2LN,/R3:/=@:Jc]&K'L +"&54667#5!##"32678B)C'g..,  $@5+?% ~~$/W37@4 Jg]&K'L##+5!#32673##"&5509.^:Er:epL~~~44@6aZZ!7@4Jg_-K'L#&%#+46632&&#"6632#54&#"#Z9fC,#+?i5dq09*T4\q3~75aZ44Z*)J@G"Je &K^'K] *L!  )( +"&5463!!"3!26654&#!33333#;55- &l!>'00ޘޗ''(`V7+,3C %!%2LLL,/S3::#;@8!Jf-K.L &#+#"&&546632&&'#3553#66IttIIutI ?7~6> ?9;?fo\\oo[[(CU TH] ^@"A@>Je(K'K`*L +"&'532653353#5#1,Ε K s ^2S1<""#O@L Je Q ] (K ]'L#"+3533##5#3#5!#3>7#39̕ѤߕP.$2p *&" z17Rp[G<"!(>@;$J R](K^'L#" +3667&&553667!3#5!6675#35`  F@yYO!;` H7!~ +M?4! kYw $^I-$(4V@S!,Jgg gW_O*)0.)4*4%#(((%%" +%#"&546632#"&'6632"3254&"32654&$jmP`PT.N0&C% V%[h#<5G >A:(,%)Jbɴ{`K7-; GT&" X*$ 29 /5!$" 8@5eU]M  +3#!#3667#39P.6: p *&"s{KopOA-,"@gW_O&&&#+#"&&546632326654&&#"1Z>9Z30[>:Y3   j|66|jj{55{j@GG@@FF-[,:@7  JgW_O +"&546632&&#"3267rQbIq/,3`!_WXPCc2+_ d~<s RSRN%@"U]M+#!5vd5ZpN{" *@'U]M +3!####N-"NNs 9@6eeU]M   $!+32#!#5#32654i~ypfh+8WPQP^p&<sC@@ e eU]M$! +3#32#!#535#32654i~yp~~fh+8pcPQP^p&<+_-@*JW_O$#'+3#"&&5467332654&#"E~SQ=|__|=OQ=CD<;DF;}THrBBrHS|@II@?IK'"$<@9JGa](K]'LU"%1#+5663232654&&##5#5!32#"&#"0&$%-$+622-\k.\f>a/nernvvnrdn/*6@3%J`.L * * +"&5467.536653'2654&'Xa8--8 #!+0.M,8/)R>%" \H2`80KDK0+?>);]G}96a;+O1e $1"6 ':,4S@P% $ 2J~_/K_ .L0.)'"  44 +"&546632&&#"3267'332654#"'6632#"&'9z, +<9~WXo/,,-ffff=F44F<zz !N" gKPX@ f (K]'L@#U f (K]'LY@  +373!7###3'.!'][Õ= r e,.""V0*").vv]"6@3J~](K'K*L%&+!#'&&'####"&'532673]  >= * <6DNs~<b"G@<"5@2Q] (K]'L +#3#5!#3>73#P.$2!o *"p17RKE["U@  JKPX@](K_'L@](K'K_.LY@ ##+!###"'532>7!#7 +M?4! mYw $^pN"-@* J](K'L+##467####3ϋpӈ"pN (L `!K-"r->, %>@;g_/K_.L!%%  +"&&54632'2654&#"7"&546324LwD|MvDyF>>GF>?G**** B[B~ZxSQQQQQQS[ )**) -, %1-@*g_/K_.L$$$$$%%"+#"&&5463232654&#"4632#"&74632#"&XNXN(OYXOOYYN%''%%''%B[B~ZQSSQQQQM" "! !" "! -,' ` `<6@3IQ](K]'L +333#5!#3>7#3P.$2p *&K17Rp[G-,'.@+J_/K_*L%*%"+#"&'532654&'&&54632&&#"sk9\)$a&.00FDQqg3\1)K ()11-D' lzr1+*I,+hS_n b2 )- @Q&,5KPX@3 2  J@3 2  JYKPX@$  g ] (K]'L@,  g(K _ /K'K_.LY@0.*('%"  55 +23533##5##"'532654##532654&#"'66;g?Ѥߕ 9x\J"c8=T:7JQ4;'](,/o,@2- %-M/"{#Ag!h<""6@3 Jh(K'L"""$#" +326753#5#"&'#"&5533267&55.<'C"!U61J(d?Q`<'E""G +WYG1"4:KPX@%J@%JYKPX@/Wgc ] (K  ]'LKPX@0 ggc ] (K ]'L@5 ggUc ] (K ]'LYY@!:965210/+*)('&$" 44+%2#"&'532654##532654&#"!#3>7!366#3$?&% "+MU'@:!$2\"!+0#/1 .$2I8p *&}%##(; M '< %17RK 5[G"$I@FJg](K'K_*L$$%%&# +#6632#"&'5326554&#"##5#Z9Ve#N@3#&!'H&"pWY2R1u"1+"p"+@( J](K_.L%#+7#5!#3267#"&&«* 7FU&pp2!u1RN""D@AJe(K^'K]*L "! +"&54633#"33254&#!333;55-&-3ڕ=(aU7+,3C [%,"N!-P/R3:"=@:Jc](K'L +"&5467#5!##"32678BP7Y..,  $@5=LrppN$/W"1@. Jg](K'L#"+#326753#5#"&55#5!B7]0+nGUfXG WY[pNF#W@JK2PX@g_(K'L@gg'LY@ ")%#+46632&&#"36632#4#"#N/W;+H&)R2XlXC3JFM  m &?*&_i+v]WN"&J@G Je (K^'K] *L &% +"&5463!!"3!254&#!33333#n;55-X&-3~8(aU7+,3C [%,"NN,M/S3-,T->,  B@?Jf/K.L   +2#"&&54633&&'567#7MvD{LwDS**Y))**ROV,B~ZB[x:549 vU6<zzi->-@H_.L(&/+#"&&54667.546632654&&&#C17P,EyMLvD1L+4$WH5#:46<2}E]@Ni65gLAW6 #4&9H* ';(8@A9&5&.,/ .j/ .j/ .rj/ .j/ .j/ .rj .j<3+3+3+ 3+ 3+3+3+k' ^ gG)&f 3+3xgG)&f 3+Z:K2PX@e8K9L@e]8LY+##33˗4 JK2PX@~]8K9L@~]8LY@ +!###!##uuLx ZZf@  JIK2PX@8K9K_=L@]8K_=LY@ +"&'53267#366773JU}#l8Vk@ Y" z 9&=.*rDm?.-N"BK2PX@e;K9L@e];LY@ +3##㨨"o"/ JK2PX@~]:K9L@~]:LY@ +!###!#5#mD~~D N"K`,=@:Jgg_.L(&%#,, +2#"&5466"32654&##532654&IGo?JNSg~}BsF.9=:8L>*!;97+T@HT  __gnngLQe0r<7>@<8>;r9//-=zKG@DG.J" HW_OCB;:KK+".5467>7>7327#"&&''2>54&&547"326678r_9=;+?& &*B2.\NbH me@ HO)! JA@8HK PX@6n~||W`P@5~||W`PY@VTEC=;'% ee +"&'7326'.#.#"'>3276654.54>732667#"&&'>32)4#8=/7F $!"+*(&2&%8 :E" |E^f(=7; %(%KVZ*@;2! @5 '3F. ")& TRCz,04 IX@U:9#"J!I~~|W_O-+II#&#&+'>3232667#".#""&&''76632326654&&54>73*3<<6)" HN *66$<)-) 1h  %24 $30 "" :6$. 1=9&77-=+| "."3S/-]Q &*#' 3267>54.#"'>54.54667>32>3232673267'6654&&#"06677"&&554&#"  40  !49-&'%  %! ,=&)I4 8L1#& " 5Z2,!% D0%<=="6 .* 7%  !>fNKg@(((+(' %$)/( ' +F(E2%& -& tz:+C<LP 71tE"+,3-P V@5$# J76 H  n  ~  |||||hW_ ONLA?><20.,&%! VV +"&'4&#"'>3232>54&#"'7>54&#"#"&&5732632>324  ,70C)VF"2 /72 &: 00 $!K &/&0!10.0# 0>$8^vq :1  &@KKEK A,:!!  l  *2'A3%/3oT#:.Y@V  - J~e_K_L,*$" .. +"&54632&&#"33#"'5326654&&##57dqjQ)<( +4G߰vBh`1t/?G$[Q9u`dbb ^ 0)36P o_Dm?'#72j%.-X@U  ,! Jgee_L+)%# -- +"&546632&&#"332#"'532654&##57[l0S5'8&.:3ɩx?euX.j,XAQ]P)WY=S, Z,)-$TaY8_:!5&$-bC@PTQN#[ nm J  ~  |  |gg g  WW_ OwufdLJA?8731'% +".546332667>7>7&&#"32>53#"&54>7663267#"&&54667032676654&&'#"&54632>54&'3< 1"$  +$>YK**8*4"6#=q[59'$#K@)9O04:':98[(C/'7R' %&,HR' -1 % 7  !1# 1<(![ .2(7&  QX-SY2%-$ $5F*)(.Rm?0%PF+44+I:( !. B(/H4$9)'QE*$ ,<"%095$P8   :V23NcuA(@h>:~@{W >(=\ sJ  ~  gggg W _ O}|wuecQOEC:8/- +".5463232667'0>776670#"&54>54&#"'0>3232>7667>32032>73#"&5467667>54&#"9A1"$  1+8J=%?P1C) O?2:4 AL%0:< 1CKH -" %. %\db+"%4nW/- +0,!#/43!:+$mvcD (,$ (1-;B(|E"3k]9 @MICG$P>OO@LD-J~ggW_O43&%$# >>+".54632#"32667.54667663>54'77>75? 1"$#22*E=-:;oA73A00 !@) !A5`|CPa=:=pX3& !21(7'   '5]; 5C8ld)32&#">32326670#"&'67>54&#"267&&#"";%=%&T)  BR+4[u@---):cI( 27=DLT-+&/UqCG(!<!HA%6D(&E +WBB<?,%<20x,9$J(4$3 %# H+  *;>5`K+  .Nb5,8 <}qZ4*$gl\3CY&D-!11!B5We0Dq"a 5@2eU]M  +3!##'3#3#aGxCCCC6k5``^~@{z ~{xM = J  ~  gg  g g  WW_ Ovtkiba][QOCA;:42,* +"&&54>54&'"#"&54632>54'#".546332667667>7&&#"32>53#"&54>766326732>7p $!   .0"01<(![U9A1"$  -$>PB) W>4"6#=q[;@-$"L@) 9O04:-A?8[(C98om !# $3> #EF=  .C-^ NcuA(@h>&5. (7&  C}XCL%-$ ,AN*)(.Rm?0%PF+44+QE1 !. O(@h+"JD() 5=,2)% ʰ3+p2F >@;  JgW_O +"&&546632&#"3267'~pIOo0]0PU+K>W)X*/VS) Zpl] 8" ; zSO|a ?@< eeU] M  +3333##'3#3#axCCCC:6[5``a &@# Jt +333#%5aL5M:"65bca\ ?@<JeeU]M %!+3!2##'3#3#6654'axBl=cxCCx$/Sm[>_65`1@54&#"&&546632254&'&"=Y0EqC ;d@0<" 0%"$#-'"1!./K+5#9#A3 3(M?&$<$%?(%# (EX{ % 4\;=hE 4*,S5.29))< 073,36aC   6NZ/556H(%'6Z4$(B(#--O:!  P8@10d vV |YL JhI  ~  ~g g  g g  W _  O:9rpRPJICA9:(& 88+".54>3232670#".#"32>54&'7".5463326677'0>7>77667>320>7"!':\S3@.."%#  /&DCF(6mY6 2,#3Jk.;!1"$  -',F= 8R,E07QB %&  G N `5%$ !RSF+ %!.Oe6&% #7A< ')+#(7&  6^;A1 ":e_/ $Ze5$ 8"'!** UL{@@=HG*Jr[6HW`PfdMKDB{{+"&5463232>7>7>766766732667#"&54>7>7#"&&54667>7>H3(!). )%7_VW/?|i# #9?>,="8f062 "$8> @@"(&,' /40#TyG=Y#3GF00$!SYP(QWg J:*;#( "=e~@Vj 5HNG2 8NUPUfd'8( DdV5-=&4^lFC2Zki'6whA!*3JK PX@( p g]K]LK'PX@) ~ g]K]L@. ~W e]K]LYY@+++3+2.,*($"!!!,!& +7&&54663332#!#"732654&##32654&#"NAޏ:4$:"z XB3=@PcD67H "(F,Pe=T #D8an=!)))$5,(1D@AJe]K_L  +"&'53265#53!!3#>, kk_ rW|4||\T+5KPX@J@JYKPX@!g_K _L@)gK_KK _LY@1/.,'%55 +"&&54675&&546632373#'#'266554&&#"33#"=T{CcgW]9lKMm'}5NIQ %VK17Pg VkR 6`>H[PC3U3,+M6N(w/eQOAR%#0/t3260++?@<Jg_K_L'%$"++ +"&&54675&&546632'2654&#"33#"Rh=cgW]9|f|JKghWjO@hR}5N 6\;M] 'NCM8t47)7lyx6N( #+K@H% JegWe_O   +"&54>323#773#2>54&&#"@Q"Bc@4D B'RCB/Qbo2 ;&KUyL.; ""(/5@2*(JgW_O  +"&54>3232676677&"#"6654'nq*SxNH`'.-^-,YI4% +{$)/L9A m]@}g><>Bd ?4 -'lo)H'< V M@Jg geU] M     +"&54632'2654#"3'3#"-2/L; qrnC\CP&%*76632326673'>54#"&1 ,!!7C%! :fO NR#Q\-;L+2-% ),$5 (&AN! ::2(+L/*U9<@4 2KO#;S@P 'J~|gW_O%$64.,$;%;##+".5467'7>32>73'267&&546326654&#"%0 ,PLR'+.4!/0*@*<)"  +M7+ ),$5 _$B),TZ%.&'1' 1o+%^jS.'{Q3FUg@d!$ LJ~~g g W _OHG54GUHU><4F5F)(#"33 +"&&54>77#"&&5467'667663273>73026676654#"26677 !*5S_W"$3$&  A #;#^:)'.v'B. 3T6N2GXx!B: "01-#"51O/BF=&{",!DA9+ G )87@ &D"(;!(@:5 ?I1GH17T,"J (+EPN; -N2(3<@ - ,)O@L  (! J_K_K_L%# )) +"&546632&&#"32677#"&'532655,zDyO8S,#=t=7/H" #M>4$ d~<sRN#1S3u%7N{&@JK2PX@)~K_KK_L@&~cK_KLY@#" && +"&'532657#4#"#3366323(  OXC3R2Xl5Hh!@?v]W)I*&_iVP/VA(5@(5JKPX@'c_K]K_L@+c_K]KK_LY@ %)%'&1 +3632#"&'##3267#"&&546732654&&#"C]}Ht^F)@ (ABsF/>.6 G;.Pe7+<#fGP m ;j*OUTM.K, N@K J I e_K]KL %& +##5#535#57546632&&#"3#zOORR/W;+H&)Uaa^H((FM  m &"p]&+,4KPX@J@JYKPX@!g_K _L@)gK_KK _LY@ 0.-+'%4 4 +"&&546675&&54>32373#'#'26554&#"33#"6Z6;2/9$7>3?& ~rPG78F(2,7 607 "F59) B/'7!%FG2sKF,KMg!!"&H,g:+"%|KPX@ "J@ "JYKPX@gK`L@gKK`LY@!  %% +"&&54675&&55333#"32653#'#4P..:3527)/*$G>rP 'G/.H>;|p02g!%KF(G2+)/5KPX@    J@    JYKPX@/  ~  f _K _LK'PX@3  ~  fK _K _L@:  ~ ~  fK _K _LYY@+10+*430515-,*/+/'&$" )) +"&'#536632366733#3267#"&'#"3&&267#Zs+- v]:J { WW,2> LV3472 }xYru))) zCY>"u$."0p79=A~*j-.9@g@d+J  g  e_K _ L;:0/>=:@;@53/909(&#"  .. +"&&5467754&#"'66326632&&#"!#"&&''2655267#/O0vv]+&'I%0+j9n9&Y:?X).W4?G`n#KB;M .>7D5%438 %M;WR)" c@ sH?Hw-$#-m94-0'"B1;8:&@#JGt* +'7.55467733267'7654''$E- ` #,' dF %E< r $ yJm L,!'H@EJ  ee _K_L#"%$"'#'%"3% +734546632!!!3267#"&'#"3&&*AtMvA'4W.)X?c7.J/ _@  O$!sY[I-,-4@'(  JKPX@* g  g  _K_LK.PX@0g  g  g  _K_L@0g g  g  _K_LYY@/.21.4/4,*$!%""" +746326632!3267#"&&'&&#"327#"&"3&&WK0eqG?5V.(Y?NyJ+ DM+:2DQmmwH?Hs6oUcU=8;1B3@0J_K]KL%$ +###53546632&&#"3|cc/W;+H&)Np(FM  m &"-+,+8DKPX@(<JG@(<JGYKPX@(gg _K _L@,ggK _K _LY@:9-,@>9D:D31,8-8%+%* +%&&'#"&&54632655447##"&546632373"326554&267&&#"+7J W43U4UK1PN1am2_Ae9 ~:657974^"1;'-&lO!' 8/5@&$ ! (#{JxFPGpO7EUFCCM3E@B *'J~~ghKL"%*"&" +#"&&5466325332654&'&&54632#"'#&#"v (+@    'D: $  @20:%  <1@I{'" 3c@`& ' 2J g g  gK_K L331/-,+)%##2#2" +3&#"#663225&#"#66322533273#"'3273#"' $ IH4  $ IH4  " IF3  " IF3 4JLO4JL5JMO5JM @ JKL +!#5&&546753'54&'66'5DD55CC5^>=__=>^2211N,1:@/+( , JIKPX@1   ~] K_K  ] L@1   ~K_K]K  _ LY@!32652:3:%#!  11 +"&546754#"#4#"#33663236632&&''255";PT@R;2R>/rW/JvTO?v]W"F*&')*&_irJYTZ2 N,#,@!JKPX@!~_K_L@)~K_KK_LY@%$('$,%, ## +"&546754&#"#336632&&''255";PSA*.D2r[3Xj*Oe" <=A>J;;]W"F*&_irJYTZ2 N,$/@ +"$JKPX@(g_K^K_L@,gK_K^K_LY@ #*"#$$ +&'#"&546324#"#336632%3267&#"9F/DWL5 !XD2r [2Xj )!"@==< Ok]W"F*&_ix'!2?k% ,)7@JHKPX@ L@ tY! +#.'566554&'7326654&'&&K &2N)1K, -,+& , #B(+OR. %) :%.J$,"+6F@J0/&%$ HGKPX@ L@ tY42 +7#&&''7&'566554&'77&&'&&4&'3266K <%H&2N)/#,%% -_W t)* \n#B(+OR. C9%)$, ::>;"*?@< &%" JHG_K_L-*%% +77&#"566327#"&''7&&'%4'326 /H##H5#9J!${ 8!K!"l;5  (5)$fA 1317#e'S-,G"@ "3+-G(08?FKPX@$ 6, 7+ '%$"JH#GKPX@$ 6, 7+ '%$"JH#G@$ 6, 7+ '%$"JH#GYYKPX@$  e_K  _ LKPX@/  e_K _ K _ L@9  e_K_K _ K _ LYY@#:921=<9?:?1828/-! (( +"&55!&&#"5663266327#"''7&'7&#"2654'267#)tlJ@7Z/*[A>j%#b:91M&,}6/NF ;5q;5 .<5 wH@Gs%'&&-0-$nH&-)L5#SQQ1"8;1B-, '.5$KPX@  JKPX@   J@   JYYKPX@'   e _K _ LKPX@8  e  e _K_ K _ L@B  e  e_K _K_ K _ LYY@+0/)("!32/505,+(.).%$!'"'    +"&55!&&#"566326632#"&'"3&&267#267#)tlJ@7Z/*[A>j%#b:NwD}7b"F1450255.<5 wH@Gs%'&&B[&&L97799::98;1B-,%1H@E  #J_K _L'&-+&1'1"  %% +"&&546632&#"327&54632#"'%2654&#"Z@W =<21 ,*)'JH(G_K _L877>8>53&$ .. +"&&546632&#"327&546327#"''7&'7&#"2654'FaK'"'NI" @J HKL +#33667I+;q7% >="\2 N, uKPX@  J@ JYKPX@_KL@K_KLY@    +2&&#"&&#"#33663266O  6>(%6%qT7  R,:2"\*<b/7,"+KPX@ J@ JYKPX@~_K`L@#~K_K`LY@*($#"" +2&&#"&&'#"&54673366"325   &F+)OO;PT@qT" ,<4$JYT<=A>-\*(%6%)OO;PT@qT7  P-" ,:2$JYT<=A>-\*<b15v2,?@ JHK PX@_KL@gLY2! +3267#"#"&'b^/\.  1_/,  ,&m@ J HK PX@g_K_L@gg_LY@%#  +"&55"#"&'532676632'4&#"326ep  1_/b^/\.(4L)X" "% {p p  ,J+Jd!#$!.@+J_K_L%%%# +%#"&'532654632&&#" K@/XU, 2R1r [S rKC"ZJKPX@K_K`L@K]K`LY@ #$ +#'##"&5332655Cr[3Xj*.D2aF*&_id;;]W@"y JKPX@)  eK_K  `L@'  eK]K  `LY@$ +3533533##'##"&55#267#HΕKKr[3XjH565DcF*&_i#t;9tK- .$ IKPX@$  e] K`  LKPX@(  eK_ K`  L@,  eK_ KK` LYY@! ,+)'#"!  . .  +2#"&546"&5332655332653#'##"&'#!00!"//]_R;2R>/rW/1l,I,Jd!#$!V)1KPX@, %$JK"PX@, $%J@, $%JYYKPX@%_K_K`LK"PX@,~_K_K`L@0~K_K_K`LYY@10%$%' +5332677'&&#"56632733267#"&''#J J% ,/:&'\$ +BK*E&=4) %w >2u"tFI(9"#o@  JKPX@hK_L@hKK_LY@"   +"&''#3736632'4&#"326AN9sjk2"-B$K ;-^ '&@&AW=" #@ JKKL +373#'#Ⱥjki b"#C@@JhK_KL" %$ +3736632#"&''4&#"326m5jk2"-B$KIAO1 '&@&AW;-Qb{~="d@  JKPX@pKK^L@~KK^LY@# +53327373#'#J Ϻjki+?5)Y$:"KC"!<@9J~K`K`L#($" +!#"&'53255467##"&53326553C:c/dqsQ2Xj*.D2u{w*| %+&_id;;]W@-+,!3zhFK)&f 3+3hFN)&f 3+3hFO)&f 3+3NFP)&f 3+3zFQ)&f 3+3~FS)&f 3+*FV)&f 3+-FW)&f 3+tmGc)&f 3+G)&f 3+`mG)&f 3+3zG?)&f 3+.G )&f 3+G8)&f 3+ mG )&f 3+]l 0+56654&&546jHNII134LI023M5( @_-K_.L$$%#+#"&54663232654&#"(1m\x0m\z*98,,89*esX­sX®z{z{z|| n !@ J&K'L +3467'73!RI|U  B[6!3@0  J_-K]'L(&(+357>54&#"'>32!#6B/()N+RE[@Fe7/Y?\7i8K=#+*&#a/3W7;b`:V&+?@<&% Jg_-K_.L%%!%$*+#"'532654&&##5326654&#"'6632YAUZ=dtZ.d,QAKC67BE/73LF*qNn*JX TF>c9'83*t+&+$h(Y+ 7@4Je&K'L   +!5!533#5467#B9VVi?u "/"'2D@A  Jg]&K_.L +2#"&'532654#"'!#66-Af;8c%%h.CG<< (2`Gt7:l  l5-,>@;  Jg_-K_.L &$, ,$&$5+4>32&&#"36632#"&&2654&#"5-Q}Y8-Ya(K<^npIvF,801"11/=ykS/y8eB#0vltCU=@4<-!@)  %@"J]&K'L+3!5!_ K_0%'55@20J_-K_.L)((5)5#! +"&5467&&5466326654&#"2654&&''+xP90C@i<=h?I7&E+?qJ"41&%14!88 / .:7 fYI[U@8M&&M9AR5H/;X0-'"''"%.0()!:)'2-%,>@;  Jg_-K_.L &$, ,$&$5+#"&'532667##"&54632%"326654&&%-Q}Y8,Ya(ED\mpIvF,801"11=ykS/y8eB#0vltCU=@4<-!@)/4- -@*_/K_.L     +"&54632'2654&#"0}~~8247743 xQSVMNURRm- 1 JK,PX@ (K'L@ ]'LY+!#467'73m VH!B  @_--@*  J_/K]'L&%'+!!57>54#"'6632!2=W+P&I5zRdsKMRpr!-%C"e.-YPE[/2Z 8(i@#"  JK)PX@gc_/L@ ggW_OY@ %$!$%(+#"&'532654&##532654&#"'6632RK:^6-b+MITX67MT:,)L)?3xGkyC]dp333/s22''e%$ZX4- z@ JK#PX@]'K](LK,PX@e](L@Ue]MYY@  +%##5!533#5467#4Y=Y !oaVr%L/3Z"A@>  Jgc](L +2#"&'532654&#"'!!66+h};e%,Y3AM@DC: -kgo~8:09 j+ $>@; Jg_-K_.L$$$$#"+462&#"3632#"&2654&#&+-3+9gl5fakr|.51/1// v puXxks1>@7:.%?'"d"%@"J](L+!5!p@~Z#'36@31"J_-K_.L,*''+2#"&5467&&5466"6654&32654&'>g?I7&E+?qJxP90C@i;%14#"4276886?/9&M9AR5H/;X0fYI[U@8M&n'"%.-'"'Y'20(#3$:#\-';@8 Jgc_/L!''$%%"+%#"&'53267##"&54632%"326654&&1-mxM;_jr{/51031ϻxgs.*wkq/@=5<.$?&$ (@%J_-K_.L'&%#+#"&5466327&#"4'3261n[x0n[z<9* *%8,esX­sX®K|z33z#- &- "!- Z 8 X.- 3Z" +  "d" & \- g=` `3+-{` `3+Wt` `3+Su` `3+r*` `3+)]+` `3+f>` `3+c,` `3+e-` `3+b?` `3+g=~ ~3+-{~ ~3+Wt~ ~3+Su~ ~3+r*~ ~3+)]+~ ~3+f>~ ~3+c,~ ~3+e-~ ~3+b?~ ~3+-& mq& ' -v& 'm & ' R_& 'r & ' I-g& 'm )y& ' -& 'm  -r& 'm -g& 'm'  tg4= ް3+-~*{ ް3+~W4t ް3+vS3u ް3+~r-* ް3+)v]*+ ް3+vf3> ް3+~c*, ް3+te4- ް3+vb3? ް3+kS' ' G QGG3+G3+5,8" %@"a]L    +%"&&54663!'3#Ad77dA'QQ,.n__n. b2W,Z" $@!a]L ! +7!2#'3#W'Bc77cBQQ,.n__n.b2Fb2 &@#ea]L +#3#3#32mmmmhggb ,@)ea]L  +53#53#53mmmmggg|Q!@JL +3#'1OchA"@J]L +3#'0NOcgBM @GW_O$" +'632&&#"@,b_-&HJBPEEM&  ><A @ JKL +#5'3&,v @JKL +5'37'#Xv,%0 #/;K#PX@. g e     g]L@3U g e     g]MY@.10%$ 750;1;+)$/%/##    +!5!3!!"&54632!"&54632"&54632!"&54632rMpN$22$#22$22$#22$22$#22$22$#22!NpMp*',.%%.,'',.%%.,'',.%%.,'',.%%.,'EOKPX@gK_KL@ggKLY@ $$$# +3#4632#"&4632#"&SUU:(''(f(''(6''&&((''3*  .@+  Jc_L$+$" +4632#"&5%%54632#"&####n########NN2####%1=L@I~~c_K _L32972=3=&$  11 +"&&5463232654&'&&54632#"&'&&#"7"&546322@  "' I@0=  % 9#  $.85?"   07;(49 0+%&'&&77Ew33!"#|)N)S!33wE")N)|# - 5@KOSWe@ JH[ZGK PX@lpn  ~  ne    feee]K]LKPX@mpn  ~  |e    feee]K]LKPX@n~n  ~  |e    feee]K]LK#PX@l~n  ~  |ee    feee]L@m~|  ~  |ee    feee]LYYYY@ITTPPLLdbTWTWVUPSPSRQLOLONMJIEC?=984321-+&%$"* +47#"&535!5!4632!!#"&547!5!&73654&#"32654'#5!5!535654&&5432w:0!W$$E$$7 *  + ¶(w:0!R% '#//////E$$ / %% /  q  //////R% '#9&"90 #/;K#PX@!g_K _ LK2PX@g  c_L@$gg W _  OYY@:8$$$$$$$$" +4632#"&4632#"&%4632#"&%4632#"&4632#"&_-('//'(--('//'(-L-('//'(--('//'(--('//'(-)%%)''')%%)'''')%%)'''')%%)'''(&&('''90 #/;K#PX@!g_K_ LK2PX@g c_L@%ggW_ OYY@:8$$$$$$$$" +4632#"&%4632#"&4632#"&4632#"&%4632#"&9-('//'(-L-('//'(--('//'(--('//'(-L-('//'(-'''')%%)'''')%%(&&('''(&&(''''(&&('''5@2 Je]L +%#''5'7#53'75373i=hUi;hi1 0$ ¼ J# IKPX@=nYXL?>1 0$ ¼ J# IkHKPX@1 0$ ¼ Jk# IKPX@1 0$ ¼ Jk# IK"PX@1 0$ ¼ Jk# IK.PX@1 0$ ¼ Jk# I@?n YX L ?>1 0 $¼ Jk# IYYYYYYK PX@W ~  ~  ||||| g KKLK PX@W ~  ~  ||||| g KKLKPX@W ~  ~  ||||| g KKLKPX@[ ~  ~  ||||| g KKLKPX@_ ~  ~  ||||| gK KKLKPX@e   ~  |  ~  ||||| gK KKLKPX@k   ~  |  |  ~  |||||gK KKLK"PX@k    ~  |  |  ~  |||||g KKLK)PX@w   ~  |  |  |~  |  |||||g KKLK.PX@y   ~  |  | |  |~  |  |||||g KL@   ~  |  | |  |~  |  ||||||g KLYYYYYYYYYY@"~|zyrp(+++-. +7"&'667.546327.546327.76327.546327&&546327&&546327&&54632>32663226632266322663226632>326632"' #                &  %/#) %' +F -, !11'% %+!60 )$, ">:  5/!)%    )%  / &*  " 8 1 +  #   %    #   $      f@U]M +!5Z@@'""&"3+9(3+#'@$]K_L$# +##5!#4632#"&GKoGG#@]L +##5!#GoGG<O)@&a]L +!35<{O{42  #/;@ JK'PX@#  g_K_ L@   g c_LY@#10%$750;1;+)$/%/##  +"&54632'7"&54632!"&54632"&54632)""))##IJKI.. ..3 -- ..)""))##<. -- .JKIJ")($$()"")($$()". .. .@GU]M +%!5!#@@ILGx@G"@9,G@x|GK)PX@]K_L@g]LY$# +#!#4632#"&GVGx|@]L +#!#GGw}2@/HW_O  +'7'"&546326' m32,4I @`9(grpb#+5I @`9)gqob/ 3H& 3H&9  #wK#PX@g_K_LK2PX@gc_L@ ggW_OYY@ $$$$$" +4632#"&4632#"&4632#"&_-('//'(--('//'(-&-('//'(-)%%)''')%%)'''(&&('''+ } #>@;JGgWg_O$$$$$" +4632#"&&&#"56323267#"&())(3%3<2K;/%4=2K;3)!!)'## "q5  "q5 +D#>@;JHggW_O$$$$$" +&&#"56323267#"&4632#"& %3<2K;/%4=2K;b())(- "q5  "q5 )!!)'##+ &aOm m3++"@]KL +!#!5!kk:*(@% ( Jc_L%*%' +467&54632&&#"#"&&732654&':2"IiY0Z&'"G!M/4OW'Q?=^6r54 0E,<.FBKW5%J6(F,(F>#4,"9 #NK'PX@g_K_L@gc_LY@ $$$$$" +4632#"&4632#"&4632#"&92$#22#$2-('//'(-2$#22#$2.%%.,''(&&('''.%%.,''=t 3+5  3+9 3+9'  3+9'9 @_K_L$$$" +4632#"&4632#"&92$#22#$22$#22#$2.%%.,''.%%.,''90 #eK#PX@_K_LK2PX@c_L@gW_OYY@ $$$$$" +4632#"&%4632#"&4632#"&9-('//'(-L-('//'(--('//'(-'''')%%)'''')%%''''(&&M @ H_L$" +3267#"'@&JH&-_bPEEP7m/0+776uo  0+''7'77nAB/AD*DA/?BOCA/BF*F@/AC9 #/;GK"PX@? g g _K_K _K _ LK#PX@< g g  c _K_K _LK)PX@: g g  g  c _K_LK2PX@8 gg g  g  c _L@> g gg g  g W _ OYYYY@3=<10%$ CA54.54>54.54>54.54>7{$$)?C8$$$$$$$$$$$)?C7$$$$$$$$$ + +8!A."'..'$* + +8!A-#'.*$$*-"7BHf@c21" FE;  '& J  h g _K]L:8$#?<8B:@+)#7$7 +3253&'67##&&546672675#"&&5&675"#327&&5=O('O<70"!5-0O&)O~E{P>Bi)/`&Hl>QE\e}!E"&-09      WwC   'YKNhn\iwn\<=tG@C AdD@6 JHeU]M+D'#7'373#73'7#'#3DEEDCFFC-\..\--]..]uxyuuyx&NPQNNQPz*/0+7'&&'6'6&')N)"Ew33!"#*#"!33wE")N)9 y%6c Y Y3+6c Y Y3+Pb0$@!U^N +33PVHb@U^N +3#53VLHP0@]L +#3#VH@]L +#53lHL(b:'  b0&  "@eU]M1613 +3!!".54>3!!")EX/4hT32Ug5/XE)b,/0B<54.#!5!2#/XE))EX/5gU23Th40/,,/0B<554675&&554&&'523G%=!XQ$1..1$RW!;'!%f/<gp/,.2mg;.j&1xU>K!PX@a]LL@eU]MY +3#3#1OOU^^xU>K!PX@a]LL@eU]MY +#53#53gOO^#^%G@]LK_QL$# +3#4632#"&%{/ !..! /G(!!(&!!%G'  %z "@gU]M$" +#"&54632#30! .. "/{))&""~"!0+'57!mmhn6 " 0+77'7mmhX7  U -K!PX@ ]LL@U]MY +74673#&&9>v8447u>9eIMa_KFU -K!PX@ ]LL@U]MY +%#6654&'38?u8348v?8cFK_aMJO'2@/  J~_PK_QL$#%( +74676654&#"'6632#4632#"&s!,+#G'4-c;Zb-3{ .#..#.&<"dOB1F! (!!(&!!q &5@2J~gW`P$*$" +#"&54632327#"&5467665535." .. ".,,#=P4,d;Zc-3$s(!!(&""&8#)eOB0F!i &@#W_O ""+76632#&&#"zO\uDS=6TUIIU!*&%c ]!!KPX@J@ JYKPX@'_ K]K` L@$]K ]  K`LY@!!%# +3#577337733#3267#"&&5#^GR+_z+_$.G*1M-q?2ststp o  NGN373@0J~]KL +35466753#'.'#53Nakk,1[UBnK#PX@%~]KK^L@'~|]K^LY@#! +3!2#4&##332653#!U _o1HGKGH3s^BvP YGWGY>PvBFOWbm@j()  ]USJ EC9 J    g_K ]LQPa_\YPWQWNLFFBA@<;:-+&$$$& +5&&5463236632366326654&'.54632&&#"#5"#"'#5&''4&#"7"5432754#"t-3$%8 .A +-/SK:5"p8d811N)+.DC7M*XSI ("H1,x  ,1H(N{9&,%'.3-(1;" !2F1`kv( &, 8L8LhMDFM `   ** ,9O29)/ %@"e]KL +!!##5!#Y~~~ *4DU@RDCBA*$%Jg_K _K_L><##$%($"%% +7'7&55#"&&54632!2#"&'''3267#"'4&#"3332654#!77.^ %.G(NF@P mpB4&NPU\O@(@%E ##C:!yAEi3F7CO(G-CK^Kf\FLCTB6. ") <$TQ[D;7H/)A@>  Je_K]L&"" +73&&54675363253&'#5&#"#533!7B[vkCC(*(*CCK?}^^~'isofgp  2sKzH~  ʰ3+#YX @ J Ht+&&'#467&&'7>737RkcLI)NF+bc,%(mM=0MI`pQ.CH%^i8+c`%aC:d)  ʰ3+ E+@(eU]M!#+35!54&##5323 *DO]l.MXSOV6u]X {KPX@_K`LKPX@_KK`L@ K_KK`LYY@   $" +4632#"&%#4632#"&2$"33"$2u/62$#22#$2.%%.,''s6|.%%.,''E&@#U]M+!!5!#"MXX#D| ` `3+#cD/@,eU]M +5!5!#!!DDuDDaP@ HGt+5>554&''5#'2C'T3 ;f'%i,)4$}!]) J@s+ʮ00#DB ` `3+#D@]L+5!#!DD ^ #/;CKSKPX@8   h g_K _ LKPX@<   h gK_K _ L@@   h gK_KK _ LYY@KMLED=<10%$ QOLSMSIGDKEKA?P* ʰ3+"/5 ʰ3+p<p ʰ3+)4@ ݰ3+'@@1 =2 > J~~  ~ gg g g  W _ O)(;964/-(@)@%# +2#'#"&5467754#"'66#3265"&54632&&#"3267GEB,J5AZQ0>7 Ntu0,%,PWaO%6(M(%/0H=6<58:11B6ʷ)T\^U H h31P  'M@A B4. - J~~  ~ gg g g  W _ OFD?=20,*%# +2#'#"&5467754#"'66#3265#"'532654&&'&&54632&&#"GEB,J5AZQ0>7 Ntu0,%,JLD2F !4.K@ ?:-/4H=6<58:11B6ʷ)b38R   0+/0 H   *-H0x@u    J ~   ~  ~g g  W _ O00-+)(%# +"&54632&&#"3267##'##"&55332655PWaO%6(M(%/0tu(K O5MZ&K PX@!     JK PX@!     J@!     JYYK PX@-   e U e ] MK PX@1   e U e ] M@-   e U e ] MYY@ &% +!'##3!#'#373#!#3#%&&'3 GCDEL i3pZ||J&#K'm&r)zHL)6@3J_K_L%#))' +7'6632'676654&'"&5463251rDhs4'  #&#,$22$#22\k"dM)<4 /%',.%%.,'}%2o@l J   ~ |   e  g  W _ O'&-+&2'2! %%+"&'#####53533533#36632'2654&#"G[p<ԣam^>c9'1,4j}}a,v`r@5;6 ~}vWI Z J  ~  ~   ~  ~  ggg  h  gW_Ous|wsuqpjhQPB@:7/-*)'% ``+"&&5467&&546677.#"327#"&5466323266326322&&54632#>54'6654.#"227'"&#"767&&'72654&'"#"&',20H*A! "$    #(     " 2C+G2  $ !"e= 2 -$(% +b    yt$![040 )& $:!Y5)) )  )  /GU'BP(4$**%2 7X!:$)A:%)> 2_ " 4+ V92U+4ZJ@G J~gW]M! +33273#'#7'#32654&##ZВL9##jl*'mJ^1KAFI.jl@f49??q213+aG@D~ ggU] M +!##3532!6654&#_ZZ5|l$c][en2UU`i8c?Pc?FAAZon$'e@b"! &JH~gU] M%%%'%' +27'7#'#7##30237&4'667*(# %=#Ҩ^E"s.1-n$/4EIl+1I3q|^) ,{{#]g$9K PX@40(JK PX@40(J@40(JYYK PX@gW]  MK PX@-~ ~gW_ O@gW]  MYY@%%%9%932,+*)'&$$ +"&'532654&'&&54632&&#"733#5467###!><)(8/9?;-6!/4%J}^^a[@e5`g = /'&9 5(.#41`+*"GUcqR@OhZLC73($   J    g W _Opnb`TRGE?=%&&&!$$$ +#"&'#"&'#"&'##5327.5432327.5432327.5463233>54&#">54&#">54&#"7U !V67U !W66V !S4B/$IE%0.FD- #%0.GE+$EI&07#  %% M  !%%Z  $$ C"SW'ps:3"SW':3"SW'sp:3  KHHK LNNL KHHK LNNL KHHK LNNjT@Q ee U ]  M +#5!#33#3#3333ve fņ||3?j*66`6Y4g6`6no)@&JHt+'7>73#'#3m BEcfDC]7:A; 6>;!,O]C@@TH9JH~ggW_O\Z,))$'-+6676632#"&5463232>54.#"#"&&5467&&54>4&&'326*2 (Y)R'?S)$FhES\*&*@(3B(.'.j40Z%50C61O.$!)=@"$7&6'OaA46\#F*^E3.& XN(@%JU]'L+!#533BnB-PN )@&JU]'L +!'#5353BĪBPN )@&JU]'L +!5#533BBKPN )@&JU]'L +!#5353Bb BP1$@!JH]'L+373?C P@JH]'L+373#=BB P%@"J^'L+3733?sBnP  @ J]'L+3753#>BB?P @ J]'L+3773#5>BBzP @ J]'L+3753#>BB0P@"1%@"JH]'L+3'753,CĻ1P&#@ J]'L+!'773-BU/P"$@!JH]'L+!'73,nBƸ2P( LJKPX@](K]'L@e]'LY@ +!#'73530Bɳ/P& %@"JH]'L +!5'73(kBsK4P&"@J]'L+!73.:B^.2P1%@"JH]'L+3573hBiSP '@$JH]'L +!753>B},WP -@*JHe]'L +!5#733;B7P '@$JH]'L +!773ԠBBPz  '@$JH]'L +!5'3>BrwP @ JH]'L+3'3#'X>ԠBBPN.@+J]'K]'L+3533#NBBBnP-N /@,J]'K]'L +35353#NBBBfPvN /@,J]'K]'L +35373#5NBBBPN /@,J]'K]'L +35353#NBBBqP1@J]'L+3'53#NנBBhPSi@J]'L+3'3#N<ܠBB xP %@"J](K]'L+3'353##N;զBBwP @ J]'L+3'3#5P>BBPa- @ J]'L+3'3#'N<٣BB$P1"1@J]'L+3'73#5N,CC1P"@J]'L+3'73#N,éBBn2P&#@ J]'L+!''73-ȠB/UP& @J]'L+3'753#N(ȠBBk4KsP( *@'Je]'L +!5#'7330B/P&"@J]'L+!'3.hB2.^P1@J]'L+3'3#N8CC#i$P #@J]'L+3'3#]:kBB!P&@J]'L+3'3#N4ҢBB&i/P  @J]'L+3'753#P:˭BBy"]Py @ J]'L+3'3#5'N4ҢBB%iP' #@ Je]'L+3'33##_8BB#e(PF%1!@J]'L+3'73.CS3P'$@!Je'L+!#'73/n0P.&@#JH]'L+!'73'ɗB7q2*P% '@$JH]'L +!''753-ɠB2P% '@$JH]'L +!5'73)ɠBrx3sP% '@$JH]'L +!'73*ɠB93P1!@J]'L+373>CvGP@J]'L+373#=BBuCP%@"J^'L+3733>mBvnP @ J]'L+3753#=BBu9?P @ J]'L+3773#5>BBvzP @ J]'L+3753#>BBv!0P@N+@(J](K]'L+!#5373}æBTnBPN+@(J](K]'L+!#533vBBPN ,@)J](K]'L +!5#533BOBPN ,@)J](K]'L +!'#533B-B#P1"@J]'L+3573:CP#@ J]'L+!739B|#P!@J]'L+!'73:mBxcSP $@!J]'L +!7539B"@XP *@'Je]'L +!5#733:BP $@!J]'L +!773:B2P%1"@J]'L+3'73.C+1&P'#@ J]'L+!'73/B/0$P%!@J]'L+!'73-jB21 P% $@!J]'L +!'7753/B͠/P%"@J]'L+!573.;Bi1P" *@'Je]'L +!#'733Ȥ0BF-(P"1!@J]'L+3'3K|  $JR~ h v. 'dD@W_O   +D"&54632"//"!00 )**) Y=j а3+~Oa 3+ozcPu*2 ְ3+N&IdDK PX@oU]M@U]MY +D!#5##dBB0nnCO;dD@0JW_O!!"" +D#"'#"&53326533265>0661<6708=;9##::B "B "-9K ۰3+,8J ڰ3+@(M ʰ3+@( ʰ3+61Q ԰3+[ML3 3+b dD@U]M +D!5!,ԞD135fQ q q3+0I 3+rI&dD@U]M +D%5!ggQ0+'%+4X0dD@t +D#`A2= *dD@gW_O +D2#52654&#<6CC6<550661<6708;9##::B "B ";f 0+77''7f*<;+<<+;<*;+<<+;<*;;*<@@b*dD@gW_O +D463"#52654&&?E:D;#/2$-#03&,02 ڰ3++^EC^v&PIdDK PX@oU]M@U]MY +D!#5!#BBnn13y* ְ3+]FdDK PX@oU]M@U]MY +D3#5#]Bx>\\>>]%dD@Ht +D5#7# ;\\;x__xe '/7?GKOW_gow$dDK PX@/-"&,-p6 e754 U  9 8  g;:g=<gA@g?>e!C B#g%#E$D"-#"g+)'H*G(F&,'&g20,..,U20,,.^K3J1I.,.NKPX@/-"&"-&~6 e754 U  9 8  g;:g=<gA@g?>e!C B#g%#E$D"-#"g+)'H*G(F&,'&g20,..,U20,,.^K3J1I.,.NKPX@6 e 754 e  9 8  g;:g=<gA@g?>e!C B#g%#E$D"+#"g)'G(F&*'&g/-+H*,+*g20,..,U20,,.^K3J1I.,.NKPX@54  ~6 e 7 g  9 8  g;:g=<gA@g?>e!C B#g%#E$D"+#"g)'G(F&*'&g/-+H*,+*g20,..,U20,,.^K3J1I.,.N@54  ~/-+&+-&~6 e 7 g  9 8  g;:g=<gA@g?>e!C B#g%#E$D"+#"g)'G(F&*'&g+H*,+*g20,..,U20,,.^K3J1I.,.NYYYY@ɤyxqpiha`YXQPLLHHA@9810)(!  }{xyuspwqwmkhoioec`gag][X_Y_USPWQWLOLONMHKHKJIEC@GAG=;8?9?530717-+(/)/%# '!'     L +D53#!5#53%53"5432"5432#"5432"5432!"5432"5432!"543253!53%"5432!"5432"5432!"5432"5432!"5432"5432#"5432"54325353!533353f_gLO;NQ6_5>y|b;g566fz.6ff6f66p.F3VF.p6gg666NP1dD@& JU]M +D#5667&&'5I6886 ., D 3  2IG1  3+O^U BdD@7~gW_O "" +D6632#&&#""&54632[SVUI8+):g$$""I\ZK*),'R!_ 0+77''7_*31/12*31/1K*21/13*21/1P0dD@% JU]M +D.'5>73E6886 ., D 3  2P1dD@& JU]M +D#5667&&'5I6886 .,( D 3  2H%}dDKPX@ ! J@ ! JYKPX@U]M@~U]MY@%$ +D#5667&&'5>73#&&'#6886 ., D 3   3( D 3  2@BB@ B@IG1  3+dfN<j#dD@  Gt +D37''7'7#F >F3883F>&F"B 0*@@*0 B"@+JdD@? JgW_O*($"  +D2632#"'#"&54632654&#"4&#"326S891<<1871<<  5  ''7228((8227iT_\dDKPX@noU^N@U^NY@  +D#7#73_"3{"3xCxCu 1dD@&W_O    +D"&'332673(d&pe,d2ea,712h^uK ; ;3+g, dD@U]M +D!5!,Xg=y,  3+u_4dD@)Wg_O#""" +D#"&&#"#6632327dESK$3 IdDAphi:MMKNK5ut 2dD@'W_O    +D2#&&#"#66(d&pe+d2tea,712h^.dD@#JHGU]M +D!55!w]DffD"H0+'77Br*r*=OOA=OOdL*dD@JGU]M +D#'73x*AOMNP0dD@% JU]M +D.'5>73E6886 .,N D 3  2H%~dDKPX@ ! J@ ! JYKPX@U]M@~U]MY@%$ +D#5667&&'5#.'5366736886 .,{ D 3   3( D 3  2@BB@ B@h 'LHMa H3+ 3+^K@U]M+!!jg^KL^L m6 !dD@  JKPX@"UWg_O@#Wge_OY@ !!    +D"&5463256673"&54632##$$0""$$ !" "! 6 V !N' !" "! 4m6 !dD@ JKPX@#UWg_O@$Wge_OY@ !!    +D2#"&546#&&'52#"&546$$##HC04$$""6 "! !"  V 'N! - "! !" ]^)dD@ Jt +D#.'#5>7YR^Z$c1po/KLc%\^S((% + $)'"H0+'77'I*r*rHOO=AOO=dT*dD@JHU]M +D#'73*xTMOApdD@JHKPX@ pWg_O@!~Wg_OY@ #+#" +D#363232654&'7#".#"#V2"2(&!'6>='>5-$(W` : @+5D.lT*dD@JHU]M +D37#x*AOM.2dD@'We_O"" +D5!326673#"&'>5#)S[N2Mg2" $$Si-(lL*dD@JGU]M +D3'#*xMOAz@,dD@!JGW_O%" +D4&#"56632'66 $8B@.A"&W>2,L 6,2'8dD@-J~W_O$. +D"546654&&546654#"'6632,W !3     ?P6dD@+Wg_O  +D"#".55332>333RJ%0)Y(4K65-_]^'J5J]<E #/UdD@Jg W  g _O%$ +)$/%/##    +D"&54632%"&54632!"&54632%2654&#"6CC64HG(())(())]>66>>57>- !##! !##! MU",[dD@P+Jg  W  _O$#*(#,$,""  +D"'#"&546326632%27&&#"2654&#"tF/:7HF9:9#8E 8%"$$# ME$G<7K%$H;#<%M9!""!89DuT2dD@' JU]M +D667#&'55",I##I,T 52>>25 Xm #/dD@$gW_O$$$$$" +D4632#"&4632#"&74632#"&E())(c())(())([##! " "! !" "!   0+''7'77''7'77#AB/AD*DA/?BEAB/AD*DA/?BOCA/BF*F@/AC*CA/BF*F@/AC CCdD@8 gW_ OCC@>:8$$#$$$$$ +D>3232>3232>32#.#"#".#"#".#" !8+ + *$$* + +8!A-#'..'#-C?)$$$$$$$$)?C7$$$$$$$$$$7K &dD@ JU_O +D"&553KMIaJ;pd "V ,dD@! JU_O +D"&553"&553MIaMIaJ;pd "IJ;pd "a(dD@t +D73#NN(a( dD@Jt% +D73#"&5467NS )(!(! ! -cC %dD@U]M +D4673#&&%#6654'3E#EE#E :1@:8 8:@1:cJC &3/dD@$U]M +D4673#&&%#6654'34673#&&%#6654'3E#EE#EE#EE#E :1@:8 8:@1: :1@:8 8:@1:- 3+hJG}xl l3+hGE|l l3+ G~ul l3+h{JG)l l3+luGIl l3+llG l l3+x(JgRlG l3+3+ JGS|l l3+ \GPl l3+l({FgXvlG l3+3+NlFGZIl l3+hpGl l3+hGl l3+h{Gvl l3+ip  3+a4p'U(dD@W_O"C +D#.#"#6632UU1JU*EqHSbX KZ H] /adD@V+J*IHGggWg_O$$$$$$$" +D&&#"56323267#"&&&#"56323267#"& "("2( $(#1' "(!3( $(#1'] L$ L#v L$ K$hG~l l3+lFG|l l3+lkFGl l3+{FGul l3+FlFGFl l3+hvJGl l3+lFGl l3+yhxFGyl l3+olFGLl l3+l|FGul l3+hJGl l3+lyFGwl l3+ JG|l l3+hoJGl l3+l|FGl l3+lFGl l3+FGol l3+lzFGvl l3+SlFG0l l3+OFG,l l3+hJGcl l3+"hFCdD@8JeW_O +D"&5463!##5#"3267k77.53c+* (,' 37|Q 3@0JU]M    +5>7335>73#" &21s$! &21| 46 (,' 46 (,'by!@ Jt +#&&'#5>7+-c8:c-+64 *+ 46by!@ Jt +#.'53667-++-c8: 4664 *+rt&@#W_O#" +#"&'332667jSVdS/0"I\ZK bJ "@gW_O$$$" +#"&546324&#"326H46CC64HM7>>66>>6e{,@)Wg_O"""" +#"&&#"#66323267L322IK440MJNI@U]M +!!Kg$@!JHW_O%" +3267#"&5467l $8B@.A"&oW>2,L 6Zq6]Q*T' Ұ3+"mFT}+0dDKPX@noU^NKPX@nU^NKPX@noU^N@U^NYYY@ !#"+D#"&5433632#50^#9.#6]6dD@+Wg_O +D2#&&#"##532660)Y(4K63RJ5-_S8&dD@JW_O"+D4632.*%#&)D*#,  * 4S7dD@Jt++D56654.54632*E('"&)!4 *  ,?6dD@+Wg_O +D233#".#"#54>9%JR36K4(Y)0_-50#dDKPX@oU]MKPX@U]MKPX@oU]M@U]MYYY@ $4!+D#"&5463!2#"'00^.##.hqJGl l3+lFGhl l3+lUGl l3+ FGl l3+jlFGjl l3+nlFGKl l3+lFGl l3+LlFGQCl l3+BQdDKPX@nW`P@W`PY@ "#+D#"&533267$TGiR^*0)1#4<7# xk'edDJKPX@pg]M@~g]MY@ "#+D#7#"&55332774Y "()Z 'D+/) 0|?dD@4 J~U]M+D#5&&5467576654&,[a^^W[c]a)0.+W*.0^IH__HI_6'(55('5yhJGUVl l3+[0 FKPX@oU]M@U]MY@ #"+#"&543!<5^#9I[^ FKPX@nU^N@U^NY@ !+53632#0^I.#1D/;ZE/;E/;/;/;l/;Z/;;qFE3+E3+3+װ3+3+3+3+q3+L6>@>|3+|3+ p #'+/dD@ee  e     eeU]M  /.-,+*)('&%$ # #"!  +D3##5#53535!!5!5!!5!5!!5!3#3#3#!~~G~~GnC[CC[CC[C"HHHHHH H}}HHHHHHHHHHHHHnCChvJG/l l3+lkFGll l3+lFG]l l3+lFGAhl l3+lFGMl l3+hpKGDl l3+OhKG<l l3+FhKGG3l l3+VhKGICl l3+ oJGl l3+hoJGFl l3+hvGG|l l3+h|JGHl l3+hGl l3+^Y&MM vJGJ|l l3+l|GKvl l3+l.GLl l3+hGll l3+lGN~l l3+l+GOl l3+lkG@l l3+PlJGP-l l3+l|JGQvl l3+hJGRl l3+]GU 3+lgJGUl l3+lFGZl l3+hiJGVl l3+h]uGWl l3+h{FGXvl l3+lFGYl l3+lFG[l l3+ljFG]l l3+G9)&f 3+#S >JKPX@ ]L@U]MY@  +#5667S(W= !M( V Zj ʰ3+.?=@:+*J~_K_L>(:5"p8dv( &, 8L8Um   -s (G.&,%+!&! !1F1`k->@;J]KK_L%( +35!5!3267#"&&'.#V.<' ?"( 8?U91*b}b /:;'u)E)(-^,!5@2J_K]L !! +"#53&&5466323#56654&FBK*96A?uQPu?@89,LPMBd ha!xMEg99gFMv"ahgBMO " @ JKL +!#57'53CCCCBbBBNE" 6@3gK^L    ! +!332#!3%32654##sH}xp%E+8eC"PQP^"g&<N:,"KPX@  JKPX@  J@  JYYKPX@# e _ K_LKPX@(U e _ K_L@0U eK _ KK_LYY@ ""  +2!3267#"&'##3366"3&&EqG?4W.)X?q bef,83,wH?Hstw"nnj8;1B53/F)H )3+K,(wKPX@  J@  JYKPX@]K`L@K_K`LY@'%!##%" +632#"'#"&53326532654&#"C4ALwD{H%bEgo*.D25<;55<;5" B~ZV++_id;;]WQSSQQQQR E@B  JIe]&K]*L +5!!5!#!'!6=K9UN77?w:>Z/"+4@    JK PX@/n o   g _K ]LK PX@. o   g _K ]L@-    g _K ]LYY@,,,4,3/-+)%#""!! +5#3533253#5"##32654&##32654&#ggC#C@A,).NEC /&1'/114)+7bbeehsPG=T #D8Lembb)))$5,(1("@aL +%"&&546323!6ev33* ! 76v7`;:A("#p(]0+'7'7c;R;R>Z>Z(2+@(eU]M +"&54633#"33DHIC~~W*-~bE@AC1S+)1( 2<@9eeU]M +"&54633#"335!DHIC~~W*-~bE@AC1S+)1~11(2   3+()2   3+(2(@%eU]M!#!+53254&##532#(~W*-~~DHIC1S+)1E@AC()29@6eeU]M!#!+53254&##532#5!(~W*-~~DHIC~1S+)1E@AC~11(2 ZEE3+( 2 3+NT.@+W_O +!3"&54632BP?NT1@.W_O +!3"&54632BPNT1@.W_O +!3"&54632BP NT1@.W_O +!3'"&54632BPNT-@*W_O +!3#"&54632BPNT.@+W_O +33"&54632NBP@NT1@.W_O +33"&54632NBPNT1@.W_O +33"&54632NBP NT1@.W_O +337"&54632NBPNT-@*W_O +333"&54632NBPNT 3+NT 3+NT*@'U]M+333#NBBNT 3+NT$@!U]M+333NBBɒ>_<zC{ --   X^9A<+( AS(S!<+B9<$<;<&<&<<1<#<<#< 9<+<+<+2Z}:Z0Z%Z:Z KZ5ZZ-Z:tZ:Z'.CUpCKFK<j(\*yN-y-O-y-N1H1lN1NNNk-yNy-N-K9X B9'(<+9<F<(<7<'4_@1g(<+B@1'<+{{j(N79{-g(>jM,}:0Z0Z0Z0Z -Z:::::<?:UUUUptZN\*\*\*\*\*\**-O-O-O-O-11?11k-Nk-k-k-k-k-<+k-KKKK9yN9\*\*\*}:-}:-}:-}:-Zy--0ZO-0ZO-0ZO-0ZO-0ZO-:y-:y-:y-:y-Z111 1-  bHK1ZlNlN5J1?5Z1E5Z1N5ZjN51-ZN-ZN-ZN-ZN:k-:k-:k-:-ZNZHZ,'.-'.&'.-'.'CCCUKUKUKUKUKUKX p9pCCCN<`\**:k-'.-(((((E((((AAc 9p)Y,aZ1Z0ZCZ: ZZ-Z;(:ZtZQ&Cp\-l5p-+&NNF-N8k-+&-Nj-NlNgNS-k- j;--F-PEF_5Fk-F_50Z%1Z:'. KZ%Z Z~ZZ1Z0Z.7Z7ZZZZ:ZtZ}:C \- Z56ZZZZ~Z#.Z\*n-uNNO-i+&NNkNLNNk-NyN-)9.-BN<NNRNfN$mNQO-N --1H11xxNkN9NEZNX X X p9(((    <7x0W9/. .p(p(:9@3<<(|Z< Bk2xxx/xA3{{){{M<d))1 wZN\*M+9:-uUKv0Z7ZO-NuZ NZN$o 1ZpNx+l5EF:k-]]':-D:-@::u: -a3Z"N~ftZyN/ZZN.+&ZNZkNlIZNBZNeZyN :-}:-C&p>p>$5<5<ZN iZNFZNZZN5< ZN \*\**0DO-1PO+1PO+i.+&OE7ZN7ZN:k-:k-:k-#$ 9 9 95<1ZNZRN/B~-y--- f & ZN :-++&2\*\*\*\\*\*\*\*\*\*\*\*0ZO-0ZO-0ZO-0ZO-0O0ZO-0ZO-0ZO- 19 1H:k-:k-:k-:k:k-:k-:k-9:-9:-9:-9:-9:-UKUKuUKuUKuUKuUKuUKp9p9p9-""$$$$$$Cy~ZyNUzK}#}:-^~-y-k-0;1P+%:NUZlNJ g U-N:k:-yNZ'*&Q&jCUpg COO'E'E0:B+&$yN#\'\29ZZa-ZfZbNxZ^ZN\*1:k-UKUKUKUKUK\*\**:y-:y-Zl:k-:k-OEZZa-:y-ZZ-ZN\"\*0!O0ZO-11:k*:k-FZ>U=UKu&ZZc-5u-C\*0ZO-:k-:k-:k-:k-p9&N--}:-5C- 0ZO-K1:y- p9\Ky-yNyN&-y-y-O+O++&u-1y-y-W-99KNN1Ni1NNKKNNNk-h->..-NNK]T]T-1111 K9X 99?EE-:uNu&W-N1lNy--+-E-0uNN^N33'3''7,r  == (j(j(((j(j($9$9(( (r3Cx7NNNNNNN(( ((K(K(j((((9(((((((vA-"n,w.-:k-}:-)ZN'-Rk.-1: -$tZyN}:Z6Nj}#}:}#:y-X 1 +u ;aVa"V+&1Gy2VVV;#-+G9k-k- V**Ks&;s) !1V gV V5ak: :l:l&&::o:e:::&"::x 7u1T3iZ.3~33N31~1rO 3q/'31r3q&Kyy-yyN36CiyyNy-E-lN17NNyN7-9B\*y-y-O-+&+&+1H1K+&3Nfi 1 3 3$73~3~133C11r==vzZyNZyNZyN}:-Zy-Zy-Zy-Zy-Zy-0ZO-0ZO-0ZO-0!O-0ZO-%Z:y-ZLZNZ>2ZN1 1ZlEZlNZlN5Z1G515Z15Z1ZNZN-ZN-ZN-ZN-ZN:k-:k-:k-:k-tZyNtZyNZNZJZJZ '.-'.-'.-'.-'.-CCCCUKUKUKUKUK99X X BBp9CCCNX 9\*N--------XQ8=#++&+&+&+&+&+&A<0.NNNNNNNNca NN  k-k-k-k-k-k-cr" FFFFFFFF_5_5_5_5_5_5_5_5\l--+&+&NN%Nk-k-FF_5_5--------I8NNNNNNNN_5_5_5_5_5_5_5_5 ^^-------IGAG_eDpNNNNNf[ZAAQv  AAQvFFFFj;j;FFpp+A[A[A_5_5_5_5_5wHyRAM+<('\ ,.9{{{x<Z$<$N< K <<b< :< }:<A@1 x 515t Z\*IZNZrNC:]l 9 GZN-RS(((Z(FF???(((02;?^Cwu--------FFFFFFFFFFFFZ-ZU""""^K[SS[[J[S[[**$$$qcZ]NyZkN[lZN5ZNIZNAU<\ZZU: F1Zxy';j}#ZZ5:%:t::b(9tt .-"[k9k95""Z"[u7ZQZ}-'w.:yCsZ@:0Z U5Z-Z:1N1k--+&&O+E-1N1-1Xk*11131N11KHF+NE'%V)***v*v*v*llNlN1--y y--&9X yyKN i-I-NNdNN,T].k-N61NNNNylN:LNX-8\*O-1.N1-K77N-RRRRRRRRRRR776F//////kFk kFk FF:%$FF'FFFf/f/f/f/f/Fv F[[[[[[[y[ [[7F7FFFFFF#FFFFFFF///////////E0FH/2F2F2D2F&&&&&&w>|C|C|C|C|C|C|C|C|C|C|C3HHHHHE/s9.2%2t-Z CC'( U:@:Z.::Z$:Z  lZ::%:'.(.b5%CZCZ6Z%::"L--z-N+&NK:RNm-No N]Nk----&<`)N)HNN-k-k-Y.A3Z7ZZKNCNK=/ QJ [W%F"A  ah%2x2 a aa =av&$(a+Z[8%++IC  W Wo 1--D-Nn/y&u&y:*:O(y-NNN,,k:-----KeT^NN cKKNPPBB~Ky-333~333C|3. A]5 /!<&E<2Z5 U0Z-b/;5O?3F+7"<#F#<$AA&A!AAA3A+A"A&A{{-{{{{){{{{{{-{{{{){{{{--}|-)--{-{{-{{{{){{{{_5WKFKaX<U%E<3%9i9i909i99B5dXw;;%'!i99##<R2I9xxw;;%'<ei9(C9<+<+<+X+:9=59!:99i9ax79%0-=#Cz9%IPIIPIX(X%BBB ((>33.`3=_`1%%%>>""AcXXXXXXXXj3X UC, u7X# g#g#g#g#}g#g#5"lP5"p)%0-'YZ'1HO,ZaXZ#D,eNNNN "&"(&&#' NNNN""&&(&#'%'.%%%NNNN%'%%%""#""""'%'%%%??NNNN%GGGGG3%%%%%%%%"%%-****+NNNNXrYi-.C[0yO@KN"vYNC-,@@6[150Q0NCC0+&1yHHSQOHd@uuuu"dH 4]"dllz?]X V--xlN]{FyoSO"uhYzgru3e_1JfL_b_b_rAe_6"+6?jnLBxy[[LOFVPZ'.C-9 hNeN`Kl<Z((Z(Z(Z(Z(Z(Z(Z(Z(NNNNNNNNNNNNNNNTTTTx0x p0h, x h @lx`HP\44hhhH Hh !"###$%%,%&''()*0*+T+,X,-0-. .P./l/l/01t282344p56677,8@8|9 9t9:; ;<<<<===>?AXAxAAABB,BPCC CDChCCCCDD@DDEE<E`EEEFFFGG<G`GHHIII0IHI`JJJJKK,KDK\KtKLLLdL|LLLLMxN4NLNdN|NNOPOhOOOOOPP4PLPpPPPPQQ$Q<QLR`RRRRRSS,TT,TDThTTTTTUU(ULUpUVVVWW0WTWlWWWWWXX,XDX\XXYY(Y@YdY|YYZ$Z|ZZZZ[ [$[<[\\\]],]P]h_$```aaa@aXa|aaaabb$b<bTblbbccccd d$dHd`ddddeeeeeff4fXfpffffgPhi jjjkkk4kLkl$lhlm$mnno$op8p\pxpppq q4qXqpqqqr|rrrs@sPs`sssttuuuuuvvw\xx<x`xxxxxxz(z{p|,|}|~L~HX|d|hD\t< $4L\ \$4DTdt TXPp<H`@`phx4pT(@Ph$<Lt,<Tlt(Ld4x l,L(x DTdtd\ p<<<<<<<<<<<<<<0̴X΀Dϴ,h҄Ӡ԰<ռ֐T؄@۰t݄ݔ4l 84LX 8 hL 8pX(H4,H,t`pp  h    p  l  ,Ph$H`x8Pt $H`8P0H(\ !d""##$H$X%|'''4'X'p''''( ($(H(`(((() )$)H)`))))***<*T*x****++,+D+h++++,, ,8,P,h,,,,---@-X-|---...@.X.|....///0/T/l////00 0D0\0t000001141L12t3X4L5467078D8889:;;h?,?<?@|AxAABBCTD8DEF$FGhHHXIpJ@JJKKLMXN4NOpPP,QQRXSST$TUVW WWX,XYZHZ[t\$\]]4]]^ ^,^L^d^|^^^^___<_T_x____``,`D`h`````aa(aLadb,cpccccd d$dPdpdddddee0efffggg@gXg|ggggh h0hHhlhhhhhi i8i\itiijLjk k0kmndoo(o8o\otooooppp@pXpppppqlrslt`uXvvwwxxypz z{{|X|h}~~Lt4|,L,LdhL4TTdPD L<@`X4hx,DPhx4(D `h@4 ,Pt(Lp h<,@<\”¨8\èPĤ,xŘŸXƀƨ ,Hnj `0Ɍɜ@P`ʄʨʸˤ$`Ϭ\Ѩp(Ӡՠհ P$<Tdt؄ؔ|ڸۼLܨ0݄Hެl@<H(d@TT8\$HlDh@dPt(Lp$Hl Dh@d<`(Hhd0T|D    dLl($8D l!"#$|%X&p'p'''(($(H(l(((() )D)h))))**@*d****++<+`++++,,8,\,,,,,--4-X-----..4.X/0T0l0000011,1D1h11112 282\2222233(3@3X3p33334404H4`44445 505T5l555556 686P6h6666777@7X7|77778 808H8l888899$9H9l99999::,:X:x::::;;(;@;d;;;;;<<<>>@>X>p>>>>>?? ?8?\?t?????@@@@@d@@@AA$AHA`AxAAAAAB BHBpBBBBCC C8CPChCCCCDD@DhDDDDEEE0EHE`ExEEEFF8F`FFFFFGG(G@GdGGGHH(H@HXHpHHHHHI I4I\IIIIIIJJ(J@JdJJJKK(KPKtKKKKKLLL4LLLdL|LLLLMM M<MXMtMMMNN4NdNNNO O@O`OOOOPP PLPxPPQQ8QhQQQQRR8RXRxRRRS SPSSSTT(T@T\TtTTTTU U0UTUlUVpVVWhWWWWWXX@XdXXYZ[\\(\@\X\p\\\\] ^$_(`(`@`X`p`````a a0aXaabtcXcccddd<d`dddde@eef8fgg8gTghhHhhiHiHiik8kllDllm4mndo$oDodoooplqrstvw$wx$yzd{X|$|}~t (h\lTlXh`H d4X$4d@lp<8 8Ph(@Xp0H`x`pP8 |Px\  tP<\ x,8\´TXx8Ƅ|ǠP̐<0ΨϬ\(@ҬԤՀ֔@Tڈ@ܔ\ ,LHhppp(@Xp 0@L,\|Th\h0<$  H 0 T ` $H, | ,Dt8XHp $ !h"#4#$%t%%%&H&&' '$'<'T'l''''')++++++,,0,H,l,,-t-.8...//4/L/0(0H0X00011$1<1`1x111222223P334H4`4444455(5@5`556@6X666677p78P8h88989X99::(:@:X:|:;h;;= =|=>x>? ?,?D??@@4@T@lA`ABB$B<BTBBBCC(C@CdCD,DPDpDElEEEEF,FxFFFFG<GTGtGGHH,HDH\H|HIJJKLM|NNOOP@Q,QRXRSTU UVdW(W@WXxXY ZZZ[\\]$^t__`8`aLabbclcdexfhg\ghdhi<ijjk<klllmXnnoppprlrsttu u$uv@vwlx,xDxylz{\}}~$~XL\DX|xL\8H$  xX0\P@<,,t<8 \Dx@4P,<$|<$tHP\ ͤθ( lLּ| DްL\|ߜ߼<\4Xp<h0,@P`p @` @` @`x8Xx @`8H0,|(T$$4`$0Hd,0H`$t ( $d "T#($l$%%d%t%%%&4&l&&&'P'((`((((()))P)x))*D*+8++,,d,,--|.$./,/@/@/@/@/@/@/@/@/@/@/@/@/@0401X2$335 556d6678 8,8899D;D;d;;<<<<=>l?@AACTClC|D4E,EH`IIJJL0MN\NP$PPQ8QQR(RpRSSLSST(TxTU<UUV(VtVW$WxWXXdXY YdYYZ(ZtZ[[l[\\t\\]@]]^^\^^_0__``L``a alaabHbbcDccdddddeDeefDffg(g|gh$hlhiiXiij<jjk0kkl$lhllmDmmn npnoopoppdpqqLqqr8rrsspsttpttuDuuv vhvwwTwwx<xxy$yxyzzhz{{8|p||||||}}},}@}T}h}}~<~` ,L(l<(XxH(HhX|X$8HL\(Ppd8L|<4`4P Xt880$t(Lp8p 4@d<`8\ 0Tx,Ptt8X(`d<dL ,@T4x 0Txl H¸\Ü@dňŬ<`Ƅƨ,PtǘǼ(LpȔȸ$Hlɐɴ<4l̼<ΌδϤ@Ѡ8Ҙ8XӸ4TtHմ քX,ؐذ<|  m ^ ^ p 0x   T Dn * ( B >F <  4VCopyright 2015 Google Inc. All Rights Reserved.Noto SansBold2.000;GOOG;NotoSans-BoldNoto Sans BoldVersion 2.000;GOOG;noto-source:20170915:90ef993387c0; ttfautohint (v1.7)NotoSans-BoldNoto is a trademark of Google Inc.Monotype Imaging Inc.Monotype Design TeamDesigned by Monotype design team.http://www.google.com/get/noto/http://www.monotype.com/studioThis Font Software is licensed under the SIL Open Font License, Version 1.1. This Font Software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the SIL Open Font License for the specific language, permissions and limitations governing your use of this Font Software.http://scripts.sil.org/OFL2   !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`a  bcdefghjikmlnoqprsutvwxzy{}|~    !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~                           ! " # $ % & ' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; < = > ? @ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ _ ` a b c d e f g h i j k l m n o p q r s t u v w x y z { | } ~                            ! " # $ % & ' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; < = > ? @ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ _ ` a b c d e f g h i j k l m n o p q r s t u v w x y z { | } ~                            ! " # $ % & ' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; < = > ? @ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ _ ` a b c d e f g h i j k l m n o p q r s t u v w x y z { | } ~                            ! " # $ % & ' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; < = > ? @ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ _ ` a b c d e f g h i j k l m n o p q r s t u v w x y z { | } ~  NULLCRuni00A0uni00AD overscoreuni00B2uni00B3uni00B5uni00B9AmacronamacronAbreveabreveAogonekaogonek Ccircumflex ccircumflexCdotcdotDcarondcaronDcroatEmacronemacronEbreveebreve Edotaccent edotaccentEogonekeogonekEcaronecaron Gcircumflex gcircumflexGdotgdotuni0122uni0123 Hcircumflex hcircumflexHbarhbarItildeitildeImacronimacronIbreveibreveIogonekiogonekIJij Jcircumflex jcircumflexuni0136uni0137 kgreenlandicLacutelacuteuni013Buni013CLcaronlcaronLdotldotNacutenacuteuni0145uni0146Ncaronncaron napostropheEngengOmacronomacronObreveobreve Ohungarumlaut ohungarumlautRacuteracuteuni0156uni0157RcaronrcaronSacutesacute Scircumflex scircumflexuni021Auni021BTcarontcaronTbartbarUtildeutildeUmacronumacronUbreveubreveUringuring Uhungarumlaut uhungarumlautUogonekuogonek Wcircumflex wcircumflex Ycircumflex ycircumflexZacutezacute Zdotaccent zdotaccentlongs Aringacute aringacuteAEacuteaeacute Oslashacute oslashacuteuni0218uni0219tonos dieresistonos Alphatonos anoteleia EpsilontonosEtatonos Iotatonos Omicrontonos Upsilontonos OmegatonosiotadieresistonosAlphaBetaGammauni0394EpsilonZetaEtaThetaIotaKappaLambdaMuNuXiOmicronPiRhoSigmaTauUpsilonPhiChiPsiuni03A9 IotadieresisUpsilondieresis alphatonos epsilontonosetatonos iotatonosupsilondieresistonosalphabetagammadeltaepsilonzetaetathetaiotakappalambdauni03BCnuxiomicronrhosigma1sigmatauupsilonphichipsiomega iotadieresisupsilondieresis omicrontonos upsilontonos omegatonos afii10023 afii10051 afii10052 afii10053 afii10054 afii10055 afii10056 afii10057 afii10058 afii10059 afii10060 afii10061 afii10062 afii10145 afii10017 afii10018 afii10019 afii10020 afii10021 afii10022 afii10024 afii10025 afii10026 afii10027 afii10028 afii10029 afii10030 afii10031 afii10032 afii10033 afii10034 afii10035 afii10036 afii10037 afii10038 afii10039 afii10040 afii10041 afii10042 afii10043 afii10044 afii10045 afii10046 afii10047 afii10048 afii10049 afii10065 afii10066 afii10067 afii10068 afii10069 afii10070 afii10072 afii10073 afii10074 afii10075 afii10076 afii10077 afii10078 afii10079 afii10080 afii10081 afii10082 afii10083 afii10084 afii10085 afii10086 afii10087 afii10088 afii10089 afii10090 afii10091 afii10092 afii10093 afii10094 afii10095 afii10096 afii10097 afii10071 afii10099 afii10100 afii10101 afii10102 afii10103 afii10104 afii10105 afii10106 afii10107 afii10108 afii10109 afii10110 afii10193 afii10050 afii10098WgravewgraveWacutewacute Wdieresis wdieresisYgraveygrave afii00208 underscoredbl quotereversedminutesecond exclamdbl nsuperior afii08941pesetaEuro afii61248 afii61289 afii61352uni2126 estimated oneeighth threeeighths fiveeighths seveneighths cyrillicbrevecaroncommaaccent commaaccentcommaaccentrotateuni2074uni2075uni2077uni2078uni2000uni2001uni2002uni2003uni2004uni2005uni2006uni2007uni2008uni2009uni200Auni200BuniFEFFuniFFFCuniFFFDuni01F0uni02BCuni03D1uni03D2uni03D6uni1E3Euni1E3Funi1E00uni1E01uni02F3OhornohornUhornuhornhookuni0400uni040Duni0450uni045Duni0460uni0461uni0462uni0463uni0464uni0465uni0466uni0467uni0468uni0469uni046Auni046Buni046Cuni046Duni046Euni046Funi0470uni0471uni0472uni0473uni0474uni0475uni0476uni0477uni0478uni0479uni047Auni047Buni047Cuni047Duni047Euni047Funi0480uni0481uni0482uni0488uni0489uni048Auni048Buni048Cuni048Duni048Euni048Funi0492uni0493uni0494uni0495uni0496uni0497uni0498uni0499uni049Auni049Buni049Cuni049Duni049Euni049Funi04A0uni04A1uni04A2uni04A3uni04A4uni04A5uni04A6uni04A7uni04A8uni04A9uni04AAuni04ABuni04ACuni04ADuni04AEuni04AFuni04B0uni04B1uni04B2uni04B3uni04B4uni04B5uni04B6uni04B7uni04B8uni04B9uni04BAuni04BBuni04BCuni04BDuni04BEuni04BFuni04C0uni04C1uni04C2uni04C3uni04C4uni04C5uni04C6uni04C7uni04C8uni04C9uni04CAuni04CBuni04CCuni04CDuni04CEuni04CFuni04D0uni04D1uni04D2uni04D3uni04D4uni04D5uni04D6uni04D7uni04D8uni04D9uni04DAuni04DBuni04DCuni04DDuni04DEuni04DFuni04E0uni04E1uni04E2uni04E3uni04E4uni04E5uni04E6uni04E7uni04E8uni04E9uni04EAuni04EBuni04ECuni04EDuni04EEuni04EFuni04F0uni04F1uni04F2uni04F3uni04F4uni04F5uni04F6uni04F7uni04F8uni04F9uni04FAuni04FBuni04FCuni04FDuni04FEuni04FFuni0500uni0501uni0502uni0503uni0504uni0505uni0506uni0507uni0508uni0509uni050Auni050Buni050Cuni050Duni050Euni050Funi0510uni0511uni0512uni0513uni1EA0uni1EA1uni1EA2uni1EA3uni1EA4uni1EA5uni1EA6uni1EA7uni1EA8uni1EA9uni1EAAuni1EABuni1EACuni1EADuni1EAEuni1EAFuni1EB0uni1EB1uni1EB2uni1EB3uni1EB4uni1EB5uni1EB6uni1EB7uni1EB8uni1EB9uni1EBAuni1EBBuni1EBCuni1EBDuni1EBEuni1EBFuni1EC0uni1EC1uni1EC2uni1EC3uni1EC4uni1EC5uni1EC6uni1EC7uni1EC8uni1EC9uni1ECAuni1ECBuni1ECCuni1ECDuni1ECEuni1ECFuni1ED0uni1ED1uni1ED2uni1ED3uni1ED4uni1ED5uni1ED6uni1ED7uni1ED8uni1ED9uni1EDAuni1EDBuni1EDCuni1EDDuni1EDEuni1EDFuni1EE0uni1EE1uni1EE2uni1EE3uni1EE4uni1EE5uni1EE6uni1EE7uni1EE8uni1EE9uni1EEAuni1EEBuni1EECuni1EEDuni1EEEuni1EEFuni1EF0uni1EF1uni1EF4uni1EF5uni1EF6uni1EF7uni1EF8uni1EF9uni20ABcircumflexacutecombcircumflexgravecombcircumflexhookcombcircumflextildecombbreveacutecombbrevegravecomb brevehookcombbrevetildecombcyrillichookleftcyrillicbighookUCuni0162uni0163uni0180uni0181uni0182uni0183uni0184uni0185uni0186uni0187uni0188uni0189uni018Auni018Buni018Cuni018Duni018Euni018Funi0190uni0191uni0193uni0194uni0195uni0196uni0197uni0198uni0199uni019Auni019Buni019Cuni019Duni019Euni019Funi01A2uni01A3uni01A4uni01A5uni01A6uni01A7uni01A8uni01A9uni01AAuni01ABuni01ACuni01ADuni01AEuni01B1uni01B2uni01B3uni01B4uni01B5uni01B6uni01B7uni01B8uni01B9uni01BAuni01BBuni01BCuni01BDuni01BEuni01BFuni01C0uni01C1uni01C2uni01C3uni01C4uni01C5uni01C6uni01C7uni01C8uni01C9uni01CAuni01CBuni01CCuni01CDuni01CEuni01CFuni01D0uni01D1uni01D2uni01D3uni01D4uni01D5uni01D6uni01D7uni01D8uni01D9uni01DAuni01DBuni01DCuni01DEuni01DFuni01E0uni01E1uni01E2uni01E3uni01E4uni01E5uni01E6uni01E7uni01E8uni01E9uni01EAuni01EBuni01ECuni01EDuni01EEuni01EFuni01F1uni01F2uni01F3uni01F4uni01F5uni01F6uni01F7uni01F8uni01F9uni0200uni0201uni0202uni0203uni0204uni0205uni0206uni0207uni0208uni0209uni020Auni020Buni020Cuni020Duni020Euni020Funi0210uni0211uni0212uni0213uni0214uni0215uni0216uni0217uni021Cuni021Duni021Euni021Funi0220uni0221uni0222uni0223uni0224uni0225uni0226uni0227uni0228uni0229uni022Auni022Buni022Cuni022Duni022Euni022Funi0230uni0231uni0232uni0233uni0234uni0235uni0236uni0238uni0239uni023Auni023Buni023Cuni023Duni023Euni023Funi0240uni0241uni0242uni0243uni0244uni0245uni0246uni0247uni0248uni0249uni024Auni024Buni024Cuni024Duni024Euni024Funi0250uni0251uni0252uni0253uni0254uni0255uni0256uni0257uni0258uni0259uni025Buni025Euni025Funi0260uni0261uni0262uni0263uni0264uni0265uni0266uni0267uni0268 iotaLatinuni026Auni026Buni026Cuni026Duni026Euni026Funi0270uni0271uni0272uni0273uni0274uni0275uni0276 omegacloseduni0278uni0279uni027Auni027Buni027Cuni027Duni027Euni027Funi0280uni0281uni0282uni0283uni0284uni0285uni0286uni0287uni0288uni0289uni028Auni028Buni028Cuni028Duni028Euni028Funi0290uni0291uni0292uni0293uni0294uni0295 glottalturneduni0297uni0298uni0299uni029Auni029Buni029Cuni029Duni029Euni029Funi02A0uni02A1uni02A2dzliguni02A4 dzligcurltsliguni02A7 tcligcurluni02A9uni02AAuni02ABuni02ACuni02ADuni02AEuni02AFuni02B0uni02B1uni02B2uni02B3uni02B4uni02B5uni02B6uni02B7uni02B8uni02B9uni02BAuni02BBuni02BDuni02BEuni02BFuni02C0uni02C1uni02C2uni02C3uni02C4uni02C5uni02C8uni02CAuni02CBuni02CCuni02CDuni02CEuni02CFuni02D0uni02D1uni02D2uni02D3uni02D4uni02D5uni02D6uni02D7uni02DFuni02E0uni02E1uni02E2uni02E3uni02E4uni02E5uni02E6uni02E7uni02E8uni02E9uni02EAuni02EBuni02ECuni02EDuni02EEuni02EFuni02F0uni02F1uni02F2uni02F4uni02F5uni02F6uni02F7uni02F8uni02F9uni02FAuni02FBuni02FCuni02FDuni02FEuni02FF hookabovecombuni0374uni0375uni037Auni037Buni037Cuni037Duni037Euni03D0uni03D3uni03D4phi1uni03D7uni03D8uni03D9uni03DAuni03DBuni03DCuni03DDuni03DEuni03DFuni03E0uni03E1uni03F0uni03F1uni03F2uni03F3uni03F4uni03F5uni03F6uni03F7uni03F8uni03F9uni03FAuni03FBuni03FCuni03FDuni03FEuni03FFuni051Auni051Buni051Cuni051Duni1D00uni1D01uni1D02uni1D03uni1D04uni1D05uni1D06uni1D07uni1D08uni1D09uni1D0Auni1D0Buni1D0Cuni1D0Duni1D0Euni1D0Funi1D10uni1D11uni1D12uni1D13uni1D14uni1D15uni1D16uni1D17uni1D18uni1D19uni1D1Auni1D1Buni1D1Cuni1D1Duni1D1Euni1D1Funi1D20uni1D21uni1D22uni1D23uni1D24uni1D25uni1D26uni1D27uni1D28uni1D29uni1D2Auni1D2Buni1D2Cuni1D2Duni1D2Euni1D2Funi1D30uni1D31uni1D32uni1D33uni1D34uni1D35uni1D36uni1D37uni1D38uni1D39uni1D3Auni1D3Buni1D3Cuni1D3Duni1D3Euni1D3Funi1D40uni1D41uni1D42uni1D43uni1D44uni1D45uni1D46uni1D47uni1D48uni1D49uni1D4Auni1D4Buni1D4Cuni1D4Duni1D4Euni1D4Funi1D50uni1D51uni1D52uni1D53uni1D54uni1D55uni1D56uni1D57uni1D58uni1D59uni1D5Auni1D5Buni1D5Cuni1D5Duni1D5Euni1D5Funi1D60uni1D61uni1D62uni1D63uni1D64uni1D65uni1D66uni1D67uni1D68uni1D69uni1D6Auni1D6Buni1D6Cuni1D6Duni1D6Euni1D6Funi1D70uni1D71uni1D72uni1D73uni1D74uni1D75uni1D76uni1D77uni1D78uni1D79uni1D7Auni1D7Buni1D7Cuni1D7Duni1D7Euni1D7Funi1D80uni1D81uni1D82uni1D83uni1D84uni1D85uni1D86uni1D87uni1D88uni1D89uni1D8Auni1D8Buni1D8Cuni1D8Duni1D8Euni1D8Funi1D90uni1D91uni1D92uni1D93uni1D94uni1D95uni1D96uni1D97uni1D98uni1D99uni1D9Auni1D9Buni1D9Cuni1D9Duni1D9Euni1D9Funi1DA0uni1DA1uni1DA2uni1DA3uni1DA4uni1DA5uni1DA6uni1DA7uni1DA8uni1DA9uni1DAAuni1DABuni1DACuni1DADuni1DAEuni1DAFuni1DB0uni1DB1uni1DB2uni1DB3uni1DB4uni1DB5uni1DB6uni1DB7uni1DB8uni1DB9uni1DBAuni1DBBuni1DBCuni1DBDuni1DBEuni1DBFuni1E02uni1E03uni1E04uni1E05uni1E06uni1E07uni1E08uni1E09uni1E0Auni1E0Buni1E0Cuni1E0Duni1E0Euni1E0Funi1E10uni1E11uni1E12uni1E13uni1E14uni1E15uni1E16uni1E17uni1E18uni1E19uni1E1Auni1E1Buni1E1Cuni1E1Duni1E1Euni1E1Funi1E20uni1E21uni1E22uni1E23uni1E24uni1E25uni1E26uni1E27uni1E28uni1E29uni1E2Auni1E2Buni1E2Cuni1E2Duni1E2Euni1E2Funi1E30uni1E31uni1E32uni1E33uni1E34uni1E35uni1E36uni1E37uni1E38uni1E39uni1E3Auni1E3Buni1E3Cuni1E3Duni1E40uni1E41uni1E42uni1E43uni1E44uni1E45uni1E46uni1E47uni1E48uni1E49uni1E4Auni1E4Buni1E4Cuni1E4Duni1E4Euni1E4Funi1E50uni1E51uni1E52uni1E53uni1E54uni1E55uni1E56uni1E57uni1E58uni1E59uni1E5Auni1E5Buni1E5Cuni1E5Duni1E5Euni1E5Funi1E60uni1E61uni1E62uni1E63uni1E64uni1E65uni1E66uni1E67uni1E68uni1E69uni1E6Auni1E6Buni1E6Cuni1E6Duni1E6Euni1E6Funi1E70uni1E71uni1E72uni1E73uni1E74uni1E75uni1E76uni1E77uni1E78uni1E79uni1E7Auni1E7Buni1E7Cuni1E7Duni1E7Euni1E7Funi1E86uni1E87uni1E88uni1E89uni1E8Auni1E8Buni1E8Cuni1E8Duni1E8Euni1E8Funi1E90uni1E91uni1E92uni1E93uni1E94uni1E95uni1E96uni1E97uni1E98uni1E99uni1E9Auni1E9Buni1F00uni1F01uni1F02uni1F03uni1F04uni1F05uni1F06uni1F07uni1F08uni1F09uni1F0Auni1F0Buni1F0Cuni1F0Duni1F0Euni1F0Funi1F10uni1F11uni1F12uni1F13uni1F14uni1F15uni1F18uni1F19uni1F1Auni1F1Buni1F1Cuni1F1Duni1F20uni1F21uni1F22uni1F23uni1F24uni1F25uni1F26uni1F27uni1F28uni1F29uni1F2Auni1F2Buni1F2Cuni1F2Duni1F2Euni1F2Funi1F30uni1F31uni1F32uni1F33uni1F34uni1F35uni1F36uni1F37uni1F38uni1F39uni1F3Auni1F3Buni1F3Cuni1F3Duni1F3Euni1F3Funi1F40uni1F41uni1F42uni1F43uni1F44uni1F45uni1F48uni1F49uni1F4Auni1F4Buni1F4Cuni1F4Duni1F50uni1F51uni1F52uni1F53uni1F54uni1F55uni1F56uni1F57uni1F59uni1F5Buni1F5Duni1F5Funi1F60uni1F61uni1F62uni1F63uni1F64uni1F65uni1F66uni1F67uni1F68uni1F69uni1F6Auni1F6Buni1F6Cuni1F6Duni1F6Euni1F6Funi1F70uni1F71uni1F72uni1F73uni1F74uni1F75uni1F76uni1F77uni1F78uni1F79uni1F7Auni1F7Buni1F7Cuni1F7Duni1F80uni1F81uni1F82uni1F83uni1F84uni1F85uni1F86uni1F87uni1F88uni1F89uni1F8Auni1F8Buni1F8Cuni1F8Duni1F8Euni1F8Funi1F90uni1F91uni1F92uni1F93uni1F94uni1F95uni1F96uni1F97uni1F98uni1F99uni1F9Auni1F9Buni1F9Cuni1F9Duni1F9Euni1F9Funi1FA0uni1FA1uni1FA2uni1FA3uni1FA4uni1FA5uni1FA6uni1FA7uni1FA8uni1FA9uni1FAAuni1FABuni1FACuni1FADuni1FAEuni1FAFuni1FB0uni1FB1uni1FB2uni1FB3uni1FB4uni1FB6uni1FB7uni1FB8uni1FB9uni1FBAuni1FBBuni1FBCuni1FBDuni1FBEuni1FBFuni1FC0uni1FC1uni1FC2uni1FC3uni1FC4uni1FC6uni1FC7uni1FC8uni1FC9uni1FCAuni1FCBuni1FCCuni1FCDuni1FCEuni1FCFuni1FD0uni1FD1uni1FD2uni1FD3uni1FD6uni1FD7uni1FD8uni1FD9uni1FDAuni1FDBuni1FDDuni1FDEuni1FDFuni1FE0uni1FE1uni1FE2uni1FE3uni1FE4uni1FE5uni1FE6uni1FE7uni1FE8uni1FE9uni1FEAuni1FEBuni1FECuni1FEDuni1FEEuni1FEFuni1FF2uni1FF3uni1FF4uni1FF6uni1FF7uni1FF8uni1FF9uni1FFAuni1FFBuni1FFCuni1FFDuni1FFEuni200Cuni200Duni200Euni200Funi2012uni2016uni201Funi202Auni202Buni202Cuni202Duni202Euni202Funi2034uni203Euni205Euni206Auni206Buni206Cuni206Duni206Euni206Funi2070uni2076uni2079uni2090uni2091uni2092uni2093uni2094uni20A0uni20A1uni20A2uni20A5uni20A6uni20A8uni20A9uni20ADuni20AEuni20AFuni20B0uni20B1uni20B2uni20B3uni20B4uni20B5uni20B9uni20F0uni2117uni214Duni214Euni2153uni2154uni2184uni2C60uni2C61uni2C62uni2C63uni2C64uni2C65uni2C66uni2C67uni2C68uni2C69uni2C6Auni2C6Buni2C6Cuni2C6Duni2C71uni2C72uni2C73uni2C74uni2C75uni2C76uni2C77uni2E17uniA717uniA718uniA719uniA71AuniA71BuniA71CuniA71DuniA71EuniA71FuniA720uniA721uniA788uniA789uniA78AuniA78BuniA78C dieresisacute dieresisgraveuniFE20uniFE21uniFE22uniFE23uni03B1030403130300uni03B1030403130301uni03B1030403140300uni03B1030403140301uni03B1030603130300uni03B1030603130301uni03B1030603140300uni03B1030603140301uni03B9030403130300uni03B9030403130301uni03B9030403140300uni03B9030403140301uni03B9030603130300uni03B9030603130301uni03B9030603140300uni03B9030603140301uni03C5030403130300uni03C5030403130301uni03C5030403140300uni03C5030403140301uni03C5030603130300uni03C5030603130301uni03C5030603140300uni03C5030603140301uni03B9030803040300uni03B9030803040301uni03B9030803060300uni03B9030803060301uni03C5030803040300uni03C5030803040301uni03C5030803060300uni03C5030803060301Eng.alt1Eng.alt2Eng.alt3 uni1FCD02C9 uni1FCE02C9 uni1FDD02C9 uni1FDE02C9dotacutecarondotmacrondieresis tildedieresis tildeacute macrongrave macronacute dieresiscarondieresismacron tildemacron dotmacron dotmacron.capuni030103060308uni030003060308uni030103040308uni030003040308 uni1FDE0306 uni1FDD0306 uni1FCE0306 uni1FCD0306uni0514uni0515uni0516uni0517uni0518uni0519uni051Euni051Funi0520uni0521uni0522uni0523uni0524uni0525uni0526uni0527cyrillic_otmarkuni20BAuni1EFAuni2C6Euni1E9ETurnedauni1EFCuni1EFEuniA722uniA724uniA726uniA728uniA72AuniA72CuniA72EuniA732uniA734uniA736uniA738uniA73AuniA73CuniA73EuniA740uniA742uniA744uniA746uniA748uniA74AuniA74CuniA74EuniA750uniA752uniA754uniA756uniA758uniA75AuniA75CuniA75EuniA760uniA764uniA766uniA768uniA76AuniA76CuniA76EuniA779uniA77BuniA77DuniA77EuniA780uniA782uniA784uniA786uniA78DuniA790uniA792uniA7A0uniA7A2uniA7A4uniA7A6uniA7A8uniA7AAuniA7ABuniA7ACuniA7ADuniA7B0uniA7B1uniA7B2uniA7B3uniA7B4uniA7B6Aogonek.loclNAVEogonek.loclNAVIogonek.loclNAVUogonek.loclNAVLcommaaccent.loclMAHNcommaaccent.loclMAHTurnedeafii10103dotlessafii10105dotless deltalatinuni2C78uni025Cuni025Duni01DDuni025Aiogonekdotlessuni0237uni1EFBuni1E9Cuni1E9Duni2C7A subscriptjuni2C79uni0249dotlessuni029Ddotlessuni02B2dotlessuni03F3dotlessuni1D62dotlessuni1D96dotlessuni1DA4dotlessuni1DA8dotlessuni1E2Ddotlessuni1ECBdotlessuniA723uniA725uniA727uniA729uniA72BuniA72DuniA72FuniA730uniA731uniA733uniA735uniA737uniA739uniA73BuniA73DuniA73FuniA741uniA743uniA745uniA747uniA749uniA74BuniA74DuniA74FuniA751uniA753uniA755uniA757uniA759uniA75BuniA75DuniA75FuniA761uniA765uniA767uniA769uniA76BuniA76DuniA76FuniA771uniA772uniA773uniA774uniA775uniA776uniA777uniA778uniA77AuniA77CuniA77FuniA781uniA783uniA785uniA787uniA78EuniA791uniA793uniA7A1uniA7A3uniA7A5uniA7A7uniA7A9uniA7B5uniA7B7uniA7FAuni1EFDuni1EFFaogonek.loclNAVeogonek.loclNAVlcommaaccent.loclMAHncommaaccent.loclMAHiogonek.loclNAVuogonek.loclNAVf_ff_f_if_f_lf_if_llongs_ts_ta.sc aacute.sc abreve.scacircumflex.sc adieresis.sc agrave.sc amacron.sc aogonek.scaring.sc aringacute.sc atilde.scae.sc aeacute.scb.scc.sc cacute.sc ccaron.sc ccedilla.scccircumflex.sccdot.scd.sceth.sc dcaron.sc dcroat.sce.sc eacute.sc ebreve.sc ecaron.scecircumflex.sc edieresis.sc edotaccent.sc egrave.sc emacron.sc eogonek.scf.scg.sc gbreve.scgcircumflex.scgcommaaccent.scgdot.sch.schbar.schcircumflex.sci.sc iacute.sc ibreve.scicircumflex.sc idieresis.sc idotaccent.sc igrave.scij.sc imacron.sc iogonek.sc itilde.scj.scjcircumflex.sck.sckcommaaccent.scl.sc lacute.sc lcaron.sclcommaaccent.scldot.sc lslash.scm.scn.sc nacute.sc ncaron.scncommaaccent.sceng.sc ntilde.sco.sc oacute.sc obreve.scocircumflex.sc odieresis.sc ograve.scohungarumlaut.sc omacron.sc oslash.scoslashacute.sc otilde.scoe.scp.scthorn.scq.scr.sc racute.sc rcaron.scrcommaaccent.scs.sc sacute.sc scaron.sc scedilla.scscircumflex.scscommaaccent.sc germandbls.sct.sctbar.sc tcaron.sc tcedilla.sctcommaaccent.scu.sc uacute.sc ubreve.scucircumflex.sc udieresis.sc ugrave.scuhungarumlaut.sc umacron.sc uogonek.scuring.sc utilde.scv.scw.sc wacute.scwcircumflex.sc wdieresis.sc wgrave.scx.scy.sc yacute.scycircumflex.sc ydieresis.sc ygrave.scz.sc zacute.sc zcaron.sc zdotaccent.scuni2071uniA78FuniA7F7uniA7FBuniA7FCuniA7FDuniA7FEuniA7FFuni0528uni052Auni052Cuni052EuniA640uniA642uniA644uniA646uniA648uniA64AuniA64CuniA64EuniA650uniA652uniA654uniA656uniA658uniA65AuniA65CuniA65EuniA660uniA662uniA664uniA666uniA668uniA66AuniA66CuniA680uniA682uniA684uniA686uniA688uniA68AuniA68CuniA68EuniA690uniA692uniA694uniA696uniA698uniA69Auni0529uni052Buni052Duni052Funi1C80uni1C81uni1C82uni1C83uni1C84uni1C85uni1C86uni1C87uni1C88uniA641uniA643uniA645uniA647uniA649uniA64BuniA64DuniA64FuniA651uniA653uniA655uniA657uniA659uniA65BuniA65DuniA65FuniA661uniA663uniA665uniA667uniA669uniA66BuniA66DuniA681uniA683uniA685uniA687uniA689uniA68BuniA68DuniA68FuniA691uniA693uniA695uniA697uniA699uniA69Bafii10066.loclSRBuniA66EuniA67FuniA69CuniA69Duni0370uni0372uni0376uni03CFuni037Funi0371uni0373uni0377 uni03D0.altCfrakturHfrakturIfrakturRfrakturZfrakturuniA762uniA763uni212Cuni210Buni2110uni2112PiDoubleStruckuni211BTurnedFuni212B CDoubleStruck HDoubleStruck NDoubleStruck PDoubleStruck QDoubleStruck RDoubleStruck ZDoubleStruckItalicDDoubleStruckGammaDoubleStruckuni2107uni212Auni2130uni2131uni2133uniA796uniA798uniA79AuniA79CuniA79EItalicdDoubleStruckItaliceDoubleStruckItaliciDoubleStruckItalicjDoubleStruckgammaDoubleStruckpiDoubleStruckuni210Euni210FscriptescriptoscriptguniA794uniA795uniA797uniA799uniA79BuniA79DuniA79FuniAB30uniAB31uniAB32uniAB33uniAB34uniAB35uniAB36uniAB37uniAB38uniAB39uniAB3AuniAB3BuniAB3CuniAB3DuniAB3EuniAB3FuniAB40uniAB41uniAB42uniAB43uniAB44uniAB45uniAB46uniAB47uniAB48uniAB49uniAB4AuniAB4BuniAB4CuniAB4DuniAB4EuniAB4FuniAB50uniAB51uniAB52uniAB53uniAB54uniAB55uniAB56uniAB57uniAB58uniAB59uniAB5AuniAB64uni2095uni2096uni2097uni2098uni2099uni209Auni209Buni209CuniA770uniA7F8uniA7F9uniAB5CuniAB5DuniAB5EuniAB5Funi2E2Fzero.lfone.lftwo.lfthree.lffour.lffive.lfsix.lfseven.lfeight.lfnine.lfzero.osfone.osftwo.osf three.osffour.osffive.osfsix.osf seven.osf eight.osfnine.osf zero.slash zero.tosfone.tosftwo.tosf three.tosf four.tosf five.tosfsix.tosf seven.tosf eight.tosf nine.tosf zero.dnomone.dnomtwo.dnom three.dnom four.dnom five.dnomsix.dnom seven.dnom eight.dnom nine.dnom zero.numrone.numrtwo.numr three.numr four.numr five.numrsix.numr seven.numr eight.numr nine.numruni215Funi2189uni2155uni2156uni2157uni2158uni2159uni215Auni2150uni2151uni2152uni2080uni2081uni2082uni2083uni2084uni2085uni2086uni2087uni2088uni2089uni2042uni204Cuni204Duni2045uni2046caretuni2041uni2040uni2050uni2E36uni2E37uni205Cuni2E13uni2E16uni2E08downwardsancorauni2E0Euni2049uni2E2Duni2059uni2055uni2E10uni205Buni2058uni2027uni2043uni2E12uni2E18uni2054uni2E04uni2E1Cuni2E0Cuni2E02uni2E09uni2E20uni204Eonedotenleaderonedotovertwodotspunctuationuni2E19uni2E0Funi2047uni2048uni2E34uni2E33uni2E07uni2E06uni2E0Buni203Buni2E11reversedparagraphreversedquestionmarkuni204Funi2E01uni2E00uni2E05uni2E1Duni2E0Duni2E03uni2E0Auni2E21uni2E30squaredfourdotpunctuationuni2053uni2056uni2E1Euni2E1Funi2E1Buni204Auni2E39uni205Duni2E32uni2E38uni2E35uni2051twodotenleaderuni205Atwodotsoveronedotpunctuationuni203Funi2023uni2E3Cuni2E3Duni2E3Euni2E3Funi2E41uniA673 upwardsancorauni2E31uni208Duni208Ebrackhalfbottomleftbrackhalfbottomrightbrackhalftopleftbrackhalftoprightleftdoubleparenthesisrightdoubleparenthesisuni2E26uni2E27uni207Duni207Euni2E1Auni2010uni2011uni2E3Buni2E3Auni2E40uni2036uni2035uni2057uni2037uni2E42 braceleft.sc braceright.scbracketleft.scbracketright.sc exclam.sc exclamdbl.sc exclamdown.scguilsinglleft.scguilsinglright.sc parenleft.sc parenright.sc question.scquestiondown.scuniA92EuniA67Euni205Funi2028uni2029uni2061uni2064uni2063uni2062uni2066uni2067uni2068uni2069uni2060uni20B6uni20BCuni20BDuni20AAuni20B7uni20B8uni20BBuni20BEuni2127uni2135uni214Buni2136uni2052uni2138uni208Cuni207Cuni2137uni208Buni207Buni2031uni208Auni207AreversedSansSerifLsummationDoubleStruckturnedSansSerifGturnedSansSerifLturnedSansSerifYRotatedQuni2100uni2101uni2106uni2103uni2104uni213Buni2109uni2139uni203Duni2114uni2125uni214C prescriptionuni214Auni211Funi2108uni2120symbolforsamaritansourceuni2121uni2123 weierstrassuni02DEuni02E5_uni02E5_uni02E9uni02E5_uni02E5_uni02E6uni02E5_uni02E5_uni02E8uni02E5_uni02E5_uni02E7uni02E5_uni02E9uni02E5_uni02E9_uni02E5uni02E5_uni02E9_uni02E9uni02E5_uni02E9_uni02E6uni02E5_uni02E9_uni02E8uni02E5_uni02E9_uni02E7uni02E5_uni02E6uni02E5_uni02E6_uni02E5uni02E5_uni02E6_uni02E9uni02E5_uni02E6_uni02E6uni02E5_uni02E6_uni02E8uni02E5_uni02E6_uni02E7uni02E5_uni02E8uni02E5_uni02E8_uni02E5uni02E5_uni02E8_uni02E9uni02E5_uni02E8_uni02E6uni02E5_uni02E8_uni02E8uni02E5_uni02E8_uni02E7uni02E5_uni02E7uni02E5_uni02E7_uni02E5uni02E5_uni02E7_uni02E9uni02E5_uni02E7_uni02E6uni02E5_uni02E7_uni02E8uni02E5_uni02E7_uni02E7uni02E9_uni02E5uni02E9_uni02E5_uni02E5uni02E9_uni02E5_uni02E9uni02E9_uni02E5_uni02E6uni02E9_uni02E5_uni02E8uni02E9_uni02E5_uni02E7uni02E9_uni02E9_uni02E5uni02E9_uni02E9_uni02E6uni02E9_uni02E9_uni02E8uni02E9_uni02E9_uni02E7uni02E9_uni02E6uni02E9_uni02E6_uni02E5uni02E9_uni02E6_uni02E9uni02E9_uni02E6_uni02E6uni02E9_uni02E6_uni02E8uni02E9_uni02E6_uni02E7uni02E9_uni02E8uni02E9_uni02E8_uni02E5uni02E9_uni02E8_uni02E9uni02E9_uni02E8_uni02E6uni02E9_uni02E8_uni02E8uni02E9_uni02E8_uni02E7uni02E9_uni02E7uni02E9_uni02E7_uni02E5uni02E9_uni02E7_uni02E9uni02E9_uni02E7_uni02E6uni02E9_uni02E7_uni02E8uni02E9_uni02E7_uni02E7uni02E6_uni02E5uni02E6_uni02E5_uni02E5uni02E6_uni02E5_uni02E9uni02E6_uni02E5_uni02E6uni02E6_uni02E5_uni02E8uni02E6_uni02E5_uni02E7uni02E6_uni02E9uni02E6_uni02E9_uni02E5uni02E6_uni02E9_uni02E9uni02E6_uni02E9_uni02E6uni02E6_uni02E9_uni02E8uni02E6_uni02E9_uni02E7uni02E6_uni02E6_uni02E5uni02E6_uni02E6_uni02E9uni02E6_uni02E6_uni02E8uni02E6_uni02E6_uni02E7uni02E6_uni02E8uni02E6_uni02E8_uni02E5uni02E6_uni02E8_uni02E9uni02E6_uni02E8_uni02E6uni02E6_uni02E8_uni02E8uni02E6_uni02E8_uni02E7uni02E6_uni02E7uni02E6_uni02E7_uni02E5uni02E6_uni02E7_uni02E9uni02E6_uni02E7_uni02E6uni02E6_uni02E7_uni02E8uni02E6_uni02E7_uni02E7uni02E8_uni02E5uni02E8_uni02E5_uni02E5uni02E8_uni02E5_uni02E9uni02E8_uni02E5_uni02E6uni02E8_uni02E5_uni02E8uni02E8_uni02E5_uni02E7uni02E8_uni02E9uni02E8_uni02E9_uni02E5uni02E8_uni02E9_uni02E9uni02E8_uni02E9_uni02E6uni02E8_uni02E9_uni02E8uni02E8_uni02E9_uni02E7uni02E8_uni02E6uni02E8_uni02E6_uni02E5uni02E8_uni02E6_uni02E9uni02E8_uni02E6_uni02E6uni02E8_uni02E6_uni02E8uni02E8_uni02E6_uni02E7uni02E8_uni02E8_uni02E5uni02E8_uni02E8_uni02E9uni02E8_uni02E8_uni02E6uni02E8_uni02E8_uni02E7uni02E8_uni02E7uni02E8_uni02E7_uni02E5uni02E8_uni02E7_uni02E9uni02E8_uni02E7_uni02E6uni02E8_uni02E7_uni02E8uni02E8_uni02E7_uni02E7uni02E7_uni02E5uni02E7_uni02E5_uni02E5uni02E7_uni02E5_uni02E9uni02E7_uni02E5_uni02E6uni02E7_uni02E5_uni02E8uni02E7_uni02E5_uni02E7uni02E7_uni02E9uni02E7_uni02E9_uni02E5uni02E7_uni02E9_uni02E9uni02E7_uni02E9_uni02E6uni02E7_uni02E9_uni02E8uni02E7_uni02E9_uni02E7uni02E7_uni02E6uni02E7_uni02E6_uni02E5uni02E7_uni02E6_uni02E9uni02E7_uni02E6_uni02E6uni02E7_uni02E6_uni02E8uni02E7_uni02E6_uni02E7uni02E7_uni02E8uni02E7_uni02E8_uni02E5uni02E7_uni02E8_uni02E9uni02E7_uni02E8_uni02E6uni02E7_uni02E8_uni02E8uni02E7_uni02E8_uni02E7uni02E7_uni02E7_uni02E5uni02E7_uni02E7_uni02E9uni02E7_uni02E7_uni02E6uni02E7_uni02E7_uni02E8uniAB5B ampersand.scuni2129uni0308uni0307 gravecomb acutecombuni030Buni0302uni030Cuni0306uni030A tildecombuni0304 overlinecmbuni030Duni030Euni030Funi0310uni0311uni0312uni0313uni0314uni0315uni0316uni0317uni0318uni0319uni031Auni031Buni031Cuni031Duni031Euni031Funi0320hookpalatalizedbelowcombhookretroflexbelowcomb dotbelowcombuni0324uni0325uni0327uni0328uni0329uni032Auni032Buni032Cuni032Duni032Euni032Funi0330uni0331uni0332uni0333uni0334strokeshortoverlaycombstrokelongoverlaycombslashshortoverlaycombslashlongoverlaycombuni0339uni033Auni033Buni033Cuni033Duni033Euni033Funi0340uni0341uni0346uni0347uni0348uni0349uni034Auni034Buni034Cuni034Duni034Euni034Funi0350uni0351uni0352uni0353uni0354uni0355uni0356uni0357uni0358uni0359uni035Auni035Buni035Cuni035Duni035Euni035Funi0360uni0361uni0362acutegraveacute acutemacronuni1DFEuni1DFF brevemacroncombiningconjoiningmacroncombiningmacronlefthalfcombiningmacronrighthalf dottedacute dottedgravedoublecircumflexabovegraveacutegrave gravemacronuni1DD0uni1DC4 macronbreveuni1DC6 ogonekabove snakebelowsuspensionmarkuni1AB0uni1AB1uni1AB2uni1AB3uni1AB4uni1AB5uni1AB6uni1AB7uni1AB8uni1AB9uni1ABAuni1ABBuni1ABCuni1ABDuni1DE7uni1DE8uni1DE9uni1DEAuni1DEBuni1DECuni1DEDuni1DEEuni1DEFuni1DF0uni1DF1uni1DF2uni1DF3uni1DF4uni1DF5uni1DFBuni1DFCuni1DFDuni2DE0uni2DE1uni2DE2uni2DE3uni2DE4uni2DE5uni2DE6uni2DE7uni2DE8uni2DE9uni2DEAuni2DEBuni2DECuni2DEDuni2DEEuni2DEFuni2DF0uni2DF1uni2DF2uni2DF3uni2DF4uni2DF5uni2DF6uni2DF7uni2DF8uni2DF9uni2DFAuni2DFBuni2DFCuni2DFDuni2DFEuni2DFFuniFE00uniFE27uniFE28uniFE29uniFE2AuniFE2BuniFE2CuniFE2Duraboveusabove zigzagbelowuni1ABEdieresiscomb.scdotaccentcomb.sc gravecomb.sc acutecomb.schungarumlautcomb.sccircumflexcomb.sc caroncomb.sc brevecomb.sc ringcomb.sc tildecomb.sc macroncomb.sc ogonekcomb.sc overscore.scuni0342uni0343uni0344uni0345uni0483uni0484uni0485uni0486uni0487uniA66FuniA674uniA675uniA676uniA677uniA678uniA679uniA67AuniA67BuniA67CuniA67DuniA69EuniA69FuniFE2EuniFE2FuniA670uniA671uniA672uni1DDBuni1DDEuni1DDFuni1DE1uni1DE2uni0363uni1DD4uni1DD5uni1DD6uni1DD7uni0368uni0369uni0364uni1DD9flattenedopenaaboveuni1DDAuni036Auni0365uni1DD8uni1DDCuni1DDDuni1DE5uni036Buni1DE0uni0366uni1DCAuni036Cuni1DE3uni1DE4uni036Duni0367uni036Euni036Funi1DE6uni2C7D commaaccent2uni2C70uni2C7Euni2C7FuniAB65uniA7AEuniAB60uniAB61uniAB62uniAB63summationDoubleStruck.miruni20BFuni2E43uni2E44uniA700uniA701uniA702uniA703uniA704uniA705uniA706uniA707uniA708uniA709uniA70AuniA70BuniA70CuniA70DuniA70EuniA70FuniA710uniA711uniA712uniA713uniA714uniA715uniA716xx"-,-xx"-,-ssF-P-ssFF-FO-{{eeh-h-{{ee--xx"-,-ccHH*~h-4th-ccHHg-m-۰, UXEY KQKSZX4(Y`f UX%acc#b!!YC#DC`B-, `f-, d P&Z( CEcEEX!%YR[X!#!X PPX!@Y 8PX!8YY  CEcEad(PX! CEcE 0PX!0Y PX f a PX` PX! ` 6PX!6``YYY% CcRXK PX! CKPX!Kac CcbYYdaY+YY#PXeYY-, E %ad CPX#B#B!!Y`-,#!#! dbB #BEX CEc C `Ec*! C +0%&QX`PaRYX#Y!Y @SX+!@Y#PXeY-,C+C`B-,#B# #Babfc`*-, E Ccb PX@`Yfc`D`-, CEB*!C`B- ,C#DC`B- , E +#C%` E#a d PX!0PX @YY#PXeY%#aDD`- , E +#C%` E#a d$PX@Y#PXeY%#aDD`- , #B EX!#!Y*!- ,EdaD-,` CJPX #BYCJRX #BY-, bfc c#aC` ` #B#-,KTXdDY$ e#x-,KQXKSXdDY!Y$e#x-,CUXCaB+YC%B %B%B# %PXC`%B #a*!#a #a*!C`%B%a*!Y CGCG`b PX@`Yfc Ccb PX@`Yfc`#DC>C`B-,ETX#B E #B # `B `aBB`++"Y-,+-,+-,+-,+-,+-,+-,+-,+-,+-, +-),# bfc`KTX# .]!!Y-*,# bfc`KTX# .q!!Y-+,# bfc&`KTX# .r!!Y-, +ETX#B E #B # `B `aBB`++"Y-,+- ,+-!,+-",+-#,+-$,+-%,+-&,+-',+-(, +-,, <`--, `` C#`C%a`,*!-.,-+-*-/, G Ccb PX@`Yfc`#a8# UX G Ccb PX@`Yfc`#a8!Y-0,ETX EB/*EX0Y"Y-1, +ETX EB/*EX0Y"Y-2, 5`-3, EBEcb PX@`Yfc+ Ccb PX@`Yfc+D>#82*!-4, < G Ccb PX@`Yfc`Ca8-5,.<-6, < G Ccb PX@`Yfc`CaCc8-7,% . G#B%IG#G#a Xb!Y#B6*-8,#B%%G#G#a B C+e.# <8-9,#B%% .G#G#a #B B C+ `PX @QX  &YBB# C #G#G#a#F`Cb PX@`Yfc` + a C`d#CadPXCaC`Y%b PX@`Yfca# &#Fa8#CF%CG#G#a` Cb PX@`Yfc`# +#C`+%a%b PX@`Yfc&a %`d#%`dPX!#!Y# &#Fa8Y-:,#B & .G#G#a#<8-;,#B #B F#G+#a8-<,#B%%G#G#aTX. <#!%%G#G#a %%G#G#a%%I%acc# Xb!Ycb PX@`Yfc`#.# <8#!Y-=,#B C .G#G#a ` `fb PX@`Yfc# <8->,# .F%FCXPRYX +-o,:+?+-p,:+@+-q,:+>+-r,:+?+-s,:+@+-t,;+..+-u,;+>+-v,;+?+-w,;+@+-x,;+>+-y,;+?+-z,;+@+-{,<+..+-|,<+>+-},<+?+-~,<+@+-,<+>+-,<+?+-,<+@+-,=+..+-,=+>+-,=+?+-,=+@+-,=+>+-,=+?+-,=+@+-, EX!#!YB+e$PxEX0Y-KRXYcpB@ o_C/ *B@vfVJ6$ *B@{n^P@- *BA *@%@ @ @ *BA @@@@@@@@@ *D$QX@XdD(QXXDY'QX@cTXDYYYYY@xhXL8& *DdDD ttfautohint version = 1.7 adjust-subglyphs = 0 default-script = latn dw-cleartype-strong-stem-width = 0 fallback-scaling = 0 fallback-script = none fallback-stem-width = 0 gdi-cleartype-strong-stem-width = 1 gray-strong-stem-width = 0 hinting-limit = 200 hinting-range-max = 50 hinting-range-min = 8 hint-composites = 0 ignore-restrictions = 0 increase-x-height = 14 reference = reference-index = 0 symbol = 0 TTFA-info = 1 windows-compatibility = 1 x-height-snapping-exceptions = control-instructions = linphone-desktop-4.2.5/linphone-app/assets/fonts/NotoSans-hinted/NotoSans-BoldItalic.ttf000066400000000000000000016277341376717241300313750ustar00rootroot00000000000000 GDEF,GPOSOԫ GSUB S zOS/2m=z `TTFAQ-cmap8 s ^cvt t4(Nfpgm9&|x mgasp glyfr\Lhead(6hhea z) $hmtx3ӌ})D2locam[2maxp& namelxpost8LprepsB,l$=D]wwIUUW##::==?BDGIfknrR]SXYaacdffhh#=AEEIIYn   9ILNOQRUVYY[\^^adffqxz          ( . 0 0 6 6 : H L L Q Q S S [ \ b b l l o t v { }                                        , / 0 2 4 5 5 = ? A B C D E I J J K K N V X _ c c f f i v w w x    ,,4<DN\\d $&/R -   # % ) + , - . / 0 1  7  )F + ,] / 0_ 2 4a 6 <d ? ?k L Ll Q Qm X _n c cv i ow r v~ x z |     @ t y } !CCvvST  "#SS   . 4 7 : ; < > @ C L P V  X  4h = > A K N P R e i /         ! " # $ * + , Y [ n r s t u x y z | }   4nDFLTcyrlgreklatnkernmarkmkmk. u&t.֪rt bXn $x~x&nnnnnnxxxxxxnnnxxxxxxnxF*d $F F8* * . $ :   nB x BB  B d*n44B"J0L0LBBB"d PP0LfB*B "0LBLRRRRXnnnnnnnnnnnnxxxxxxxx**FFFFFF****dddddddd****8FFddnx~~~~~~~~~~~< <* $%&'()*./2345679:;<=>FYZ\^cm} #%'56789:<>BDFUZ[\^_`bdfgkmnopqrsuv{}<=ADFGMPQSTUV\]ackmruvxz{|}   &(*,.02468:<BCDEFGHIJKLMNOPQ];<CDEFGHIJ}~          79:<#%'579LNP]!"$B A       m       -ZM(((-<7<#%'79LNP]-d79:<#%'579LNP] ; -2"PF mdkqmdkqq~<8Y[^bgnopru =abcdefopqrstuvq[\^dgk  =]v{~;<=>?@ABijklmnwxyz{| (v{;<=>?@ABwxyz{|0 v{};<=>?@ABwxyz{|2v{~ ;<=>?@ABwxyz{| S] SX9 MST[ack|~ "o~oqsoos  STW& dM]ack * dM]ackttMackX* M]ack + dMN]abcdkl XX\^X2W MSack| + MS]ack|;"6;"2,6;< "" "oqsq~brbnorso-K-<                                   <<     ZZ           BFTPY_((222222 22222222(<( PPF<( ((F2j<((d~~~2( $$&'./ 24 7>DEHINNRSUUWWY\^^#mm$}}%&,-.3:AEFKLVWXY\]^_`aefi jpqrs#)t++{--|//}11~335:<<>>BCEGUUY^``dgkkmmoprrtuxy}}==ABDGKKMQSWYY[[ _m ry{~!%124@EFIKMQRXYgioyz!!&>@@BQ]^CJWXgx} !  +-!27}~8:;FPVal |   p p     A;:;$$&&(''..F//'2233U4477288 9:$;;F<<==>>>ADDIIQNN9UU8WW.YZ [[9\\ ^^AmmO}}N( U ((((RF9'''R''  888##2$$.%%2&&.''2((.)) ++ -- // 11 33 55$66 7788 99::><<>>>>BBCCFFUUYYZZ[[ \\]] ^^``WddeeffVggkkmmTooWpp rrVttuu xxyy}}PPX #"/#10"0S/"##=<<  !!<!<"E$ $ $  :;;ON== AABBDD&EEFF%GGKKMMNN6OOMPP!QQ/SS1TTLUU1VVLWWKYYK[[0__``aabb6ccdd6efgghhiijjkkll6mm/rrss ttMuu!vvSwwxx@yyJ{{?||5}},~~05, @E?/" IHIH5,  ?GG   1=1=0"E@J5,,4+4+ 4+4++           &&((**,,..002244&5566&7788&99::&;;<<&==>> @@ BB%CCDD%EEFF%GGHH%IIJJ%KKLLMM NNOO PPQQ ]]2^^. CJWXghin ovwx}     T !!}}Q CBCB7- *  )  3 p p= D D D@ @ J,A,$$&&**224477288 9:$<<==F@@JDDFHIIYJJ+PQRRSSTTUUVVWW*XXYZ \\ ]]:``JmmW}}V]  ++++        ""##2$$*%%2&&*''2((*)) **++ ,,-- ..// 0011 2233 4455$66 7788 99::F;;:<<F==:>>F??:BBCCDD]EEFFGGIIUU8WW7XX6YY5ZZ3[[1\\4]]^^Gdd\ggGkk\pp%uu%vvwwxxyyzz{{}}XXTIT! !/0 # Z/"!#E    . D-C B B.$ $ $  AS@,S@,  ,WV^==%@@AABBDDEEFF GGKK LLMM?NN>OO(RRSS0TTVVZZ[[#\\]]"^^__`` aa?bb>cc?dd>eeff gghh iijj kk?ll>mmnn sstt(uuBwwxx({{||}}~~#(B!C  ZRQRQD!C"-"-POPO "-0E0E0E NN#   #/././."-(DDM M LKLK  !C            !!&&''(())**++,,--..//00112233445566778899::;;<<==>> ??@@ AABB CCDD EEFF GGHH IIJJ KKLLMM NNOO PPQQ ]]2^^*1%;BCD8EJKLMP=QR7SV<WXY^ _`6afghinop5qvw|}~3;1H4 G8 765   I%13 4}}~~Y[  U  ) '  &  9 p p q se fm$=D]ww45LIkUUW##::?BDGIfknrR]&S'XYfaahddiffjhhkl{!=AEEIIYn;KQRVX]^_`  b dg9iILNORRUVYY[\^^adffqxz   3  4  8  9 ( ,: . .? 6 6@ ; HA L LO Q QP S SQ [ \R o oT q sU v {X } ^ c e g h j k l m n p s w x             ]*"`],JFR@J]<H]lJx"*xFRx]>]]B]v]*]*]*]*]*]*P@````J]]]]]Rllll"x,******FxxxxD]]]]]]**]**2FRFRFRFR*`x`x`x`x,,,8"f>8DJFRPVFRFRH\JbhJn]]]]]]JTtzHHH]]*lllllB""]**PR(F]*"H`J@JFX]:]"<x<"^]]$:]:`HH\]t]*J"HL`]t]t:@]:]<x(: J*|x]DF]FR]j]t"^8Lvx|^866DH\BBB"zx@F`x ]*0LR0 <R((" (.4:J@H\FLRX^dj]t]tDBpv|R@F"",]**]**P`xJeJe]t]hL]]RR^8]t $*x]06F*<BHNP.TZ`flrx]**]**]**]**]**rx]**]**]**]**rx~.`x`x`x`x`x`x~.]]]]]]]]]]FFFFl""*]tJ]t^84J*J]tV^@R.n"<*::hhe: eH&ntz,28>DJ]**]]lllll]**]**PV,J\b\bhLntz,J]**]**`x`x]]]]llT]**]]]]]]]]"`]*H]@||>`"J*]t]t^8*e   h"(.4:@FLR|||X]^dj||pv|vv>^8FR^8]XFRR^8x <B^8^8e$^8*06<BJTHNT]**4Z ` flr``x~  z &,28>DJPV\bhNntz "x(.4:@FLRX^djp`x`xv|v|]]>,J@J ]]]]]]]]$$*0H6<HH6<]BHNTZ`fllrllJx~Bx]x]"B*I:I:(]]]]]] &,28>D::::::::JPV\bhh]]::ntz@@@@@@@@]*]*> ""(.4@@@:@FLRX^djpJ^8HHv|j]J @ ]*$JJJFR,*06>>8>>DJDJPPPPPPPPPV\JJJbJttttttthtntz]tJJJJeeeee    7"(.4L:@]FL]RX^djpvFR|]FE\]*]tJ]>]> >>$*06<BHNTZ`flrx>0~<J#=.###,#j##`#1####T,G90='q50< f0|<0<GB 0k<0<=0<0< 0< 0 <0<s0?<x0<X{v^0<6(...Y.......*...(Q.0WU..0xW!y2W*e 0?.XdVfHz` PwIjV'sw2~z.*b% V{2  &5+S;6 eL,}9t'Os$..\_ ..R^338:..)"&Z1..YR.\9_808F.f. ..WV 88.3._*0>>>>>>>>>>>>>^0>>>>>>>>>>*>*>>*>>>*>>>0>>>>>>>>>>>>>>>>*>^^>>>>>>>^^>>>>0>>>>>>>>*>>"(.4:@FLRX^^^^^00000>>>>>>>>>>>>*>*>*>*>0>>>>>>>djpv|>>>*f>>>   $$$$$>*>006<BHHNTZ`f>lreeH+2<{eeeee^eceesexeeeeeeeD<eeeee+e}cD'c#?)#&#v#%#2eh DxDPDeeFf H m$=D]ww45LIkUUW##::==?BDGIfknrR])S*XYiaakddlffmhhno~!=AEEIIYn>NTUY[`abc  e gj9lILNORRUVYY[\^^adffqxz   6  7  ;  < ( ,= . .B 6 6C ; HD L LR Q QS S ST [ \U o sW v {\ } b g i k l n o p q r t w { |              9 f Z9~#f `#$ l#Z r9 9$ <9~ f$\D:HH :$8H$$$ $ H: H !9l#  :"""8t$ f444:::>LLLD9J`\P(((Vz\nHTTT@@@*bhTTT ppp6:2n,.9Htz   Z:4T#f#<$ F `$@$ H l$ l$ l$ rH##RLTX^$ X^ D#xJP#<# rPV \b `hntznH&I9  "("($&\F. 4:@#FLRX^dj#&p9Hv|"(,. Z:*64T `$9: $*06LT<B<BHNTZ`f f#lrx~x~&  9~9l6: H6:#$$ H 99~^$##9#f$#H9l9~ H4:&&,F28x> DJPV\bhntz"(:@LTpH&,9: "(,.4T:@FLTRX^djpv| H #B@ 4: Z:9 f9~:# >, Z$@H$< HH : H$&#Hf#  $#$5J5J5J##$ *0 <6<<<BH TTNTZ9l#`flrx:HII<(~$&#$H# <HZ:H: & ,9~28>DJP#H$9:V\6: fb$ f$9H\:hn :H ##t:z Hp "(.4:@FFLRX^djp v |60xZZ rx 2V  H  $*06xH<BBHHN2V2VxxTZ`flrx~     tt Z: Z:$$$ `$ &,$ $ l$28 l$ l$>D#Z JP rH rH rHV\bhntntz6:$ $  DJ#JPPV L\bhnttz r$$z   $:$$$ " r(. 4:@FLRHX^djjjjppppvvvv||||#B##B# r 9  $$$$ l   $ * 09$9$ r 6$ r < B H N T9 Z ` f l r x## ~:9 H ###$ $& ## # # ##: $ HH 6:6: $ H H#H H ! H:$H$#!!!!&! !! !! !,!&!,!2!8!>!D!J!V!P!\!V!\!b!h!t!n!t!!!z!!!!!!!!I!!!!!!!!!!!!!!!!!!"" """"""""""(":"."4":"@"F"|"d"L"X"R"d"X"^"|"d"j"p"v"v"|#""#"""""""""""""""""""""""""""""##M# #M###$#*#0#6#<5#f#B#H#N#f#T#Z9#`#f9~9##l#r#x#~##:#5J####3:###H##5J####$#####$$$9$$$$ $$8$&$,$2$8$>$D$J$P$P$V$V$\H$h$b$h$n$t$z$$$$$$$$$$$$4$$$$$$$$$$% EumDD5H "mEKM(Fc FO"C3  Tg ="""T"Y] zaBLI g4?R"}","Kc[z"t""+ "l""m"z"""BL "7" }<FlmXmWZEZ"""H"J"v"">,-gLnsS >>,-gs> |">>"g>[b"m"O}n6tM"|u?xk? XWrqWAmmz{"V FTU-  WN"(%"d|x4"G"O"K"7-""": """" ,":""qF";"X" "Y9dn,k">ggTggg~9"Os}Vs"v,"""""""Z")""~""a"6"-""t"""""""."'">:L$"\SGk_e/8PgvgN9ggggggCSggk#g"y"g gg5g"ggggg4ggpgg*g'g.gggg g8wm+*^q*<m!2= #{qhRmHI$d|GJ\#{^XJ"jiXMkMhEiEBB 5*  *   \!05c* " \*N=N*~ \0"8""""" \""l"q"" \""""|""b"m7"" `G:m  `m ";"a5j"D"'"f""z z$z21<"""fi""*"`2p"),$,ph<sggu"d"+"*""_"%"H>""'#VFyF#IF#gF"eF"jF]'\"YZ\#P-F*F'"vOsF"'"#5FFF"UF #F FF#"FF'"#FCFvF~#~"S#S"$FFX")F'#"iFj@FF"#OF.F]"Z#FR#R"Pg{"o"p""]"N"n"""h"6ggM""f"i""lL8?"N"hhI-Vyg 7OXpY.d"") )$=D]4:CINTY_du  &)?HIUUW[^_acefhikkmmoprrtu|}    ?BIIKLww !"#(*+./01"2$3[>AkLQo]^ueewxy|   ++QQSSVXbbzz|}%',..026689;;?BDDFGJP SSXYff9JCJQV_fo=@EEII_`       !#"")..*JL+NO.RR0UV1YY3ad4qx8}@GT\]w    * + 6 6 S S q q } }                      \ h t p$ f V V  z 8 b n 6& 8 66 $ h 8 * 0   h $$$$VVVVV 8 8 8 8 8 8 n 6 6 6 6hhhhh  8 8 8 h n h n h n h n 6 6 6 6 6 t 8 t 8 t 8 t 8 p $$$$6$  $ffffVhVhVh * * * 0 0 0 0          0 \ p$  V z$  h 2h $$  \ pV h z 8 6h n  6 066    D  8 6 h n $$ 8 8 6Vh  8 8 8 8 8 8 8 8 8 8 8 8 6 6 6 6 6 6 6 6$$6VhVhVhVhVhVhVh     8$Vh      8 8 t 8  $VhVh t 8 8 8 6 6$$VhVh * *   p  8 6VhVhVhVh  h n 8 8tV$*06<B nH n6 h hV 8  NTZ`flrrx~ > > > > D      V  &  , 2 8 > D J P V \ b \ b \ b h n 6 6 6 6 6 & t 8 p  p  p  p  p $6$  $  $  $ffff  VhVhVhVh * * * * 0 0 0 0 0              z z  8   "  " ( ( L . . . 4 : @ : @ F F hhhhhh hh   "  " ( ( . 4 : @ : @ F F L R X ^ d j p$$ v | \   8     f V t   $ f 6 $ $ $  8 8    8 $ * 0 8 66 < B H N N N N N N N N N N N T Z Z Z Z Z Z ` ` f f f f f f f f f f l r r r r r x x x8888888888 ~ ~  V h t    & &  & , , 2 8 > D J P V \ b h n t z 6 "vox,_gNggggNYZVQ",^<wP@&gggpGggk2Lgyggug "9"b":"-"UBIn{DBFGZbukUY~%qOa>{.)\hh"y"&"")"""S"FAYF@F8FsFFFzFFYFWFFF.FF4FFGFFFF-F:FKFFF3]8}""N"x"hhhWmg0-G:`"?""TP $6HZZttV p  > $ ] B  Q"(.4=Z $*06<E0E"0q   c*Q - : l tB$T6BTf  ne eoe _"(.4((b/(/#2#  ^2cQ - 0 : b l t f $6HZZttV  q hZ |o at$   @"m" W"""(.4z-J$*06<XJXD ,"C" LJefc*Q - : l t f<NZfr~n 2>Pbn H|" v"  =o " " ?"   vW  FF $ o"""(.4^{0$*06</uA/uD  @@   # % ) + , - . / 0 1  7  8 6 <: ? ?A L LB Q QC D     " $ ( * + , - . / 0  6  )E + ,Z / 0\ 2 4^ ? ?a Q Qb X _c c ck i ol r vs x zx | { E:v"(.4v:@FLRX^vvdjpv|r? 5n &,28>DJPV\bhntz "(..4:@FLRXXdd^|ddjpv|4&& 00(.=#4O98((1Mb&O*%!`p ,Ilnl G4FlC RlPl0 JlNlW-lZlClGlHlKl  2p @    t y }  &,28_ {`  "CCvvST  "#SS   . 4 7 : ; < > @ C L P V  X  4h = > A K N P R e i #"# & ) , - . 0 2 5 6 ; ? E  G  ,W / 0o 2 4q = >t A Kv N P R U X _ c c i o r z | 6<BxHNTZ`lflrx~ ,,bb, bDbD &D,28   >DJ PV \b              hn                                tz                                         ""H""""J"`"P"^"\"V"j"Q"c"" N3"/"H"X"%"L"C""."8" qB"A""r">"-"@"Y""L"Yl2"/"3")"7"1"x","3"8"!^FFtF7F F9FBFEF3F'F4"")""'" "W0I"9C9";"J":"`flrx~ &,28>DJPV\bhntz "(.4:@FLRX^djpv|D>h~n\d jVXTxElcUENdJX[UN@H__b\Wdb\Xc9VUZ;ayll[NPS\6IRNVGV"QL`EaR`Te`CaC1paF`@\O~b##t#=#]#](^jL>S^GF@3HBsFF~FjKRFwFFvFu{FuFyF|F  j        $ * , Y Y [ [ n n r u x z | }  %$]tK"+X^dpjpv| $FF9FFF FF=FFFFuFFFF "DFLTcyrlFgreklatn  SRB 2  "CAT JMAH tMOL ~NAV ROM       aaltc2sccaseccmpccmpccmpccmpccmpdnomfracliga lnumlocllocllocl"locl(locl.locl4numr:onum@ordnFpnumLrtlmRsmcpXsubs^supsdtnumj "#     $!%L`~llN > > ` $ J J b * j *D   5 `N  & ) , 0 3 7 Q Q9     ! " # N P$ n n' s u( y z+  - . / 0$')( 9012345678LM%g|K^0:DNj|",6@JT    LD   F 3     LE   G 4 :BJRZbjrz                            :BJRZbjrz - / 1 0 . 8 ; : 9 C E G F D = ? A @ > 3 5 7 6 4 , B < 2:BJRZbjrz e g i h f q s u t r | ~  } w y { z x k m o n l d p v j:BJRZbjrz I K M L J U W Y X V _ a c b ` Z \ ] [ O Q S R P H T ^ N:BJRZbjrz           ' ) + * ( ! # % $ "       & $ &  L L L L$(,28DHLRX#% n&0:DNX        $.8BLV`jt~            $.8BLV`jt~            {  }~34HI#$ ]^ >(>JJyOy/y n o p q r s2 0 1 2 3 4 5 6 7 8 9   KNOPQSVW$ :{tu'(;)*<   Q   "B*    $ $,$D2Rl|l|$2DR .        .      .           :     M          A B C D E F G H I J K L "$%&'()*+,-./0123456789:;<=>@^`cq  !#%')+-/13579:<>BDFH] 8     M          A B C D E F G H I J K L ">@DEFGHIJKLMNOPQRSTUVWXYZ[\]^`cq   "$&(*,.02468;=?CEGI^ B    6 "(ILIOILOI IXKXJ^2B  @)GOOG!--%  J ~01ac67Y] AEbw~  OP\_'/=?EMWY[]} d q  !_!!,m,-.Ds}!.Ze/ 12bd78Z^ BFcz PQ]`(>@ HPY[]_ f t !!!,`,n-.@t~".0[  HJHP ~GtI=EvZ;9753210/-,+)(&%+Mc5ee`Y`baa^58<.>D<RfjHhTHI#$&'#$JKLMNOPQR  n u z s t y  y ~ z  { |<=>L R S T U Vpqrstuvw  <  =  >  ? ? = > w o p q r { v x i | } j k l m ~    AB+,!LMNOPQ*{|$%&' ()*   ^  R +,-./0 1 ? i 2 A @ : S = > b c K } k ; < ] m B x V N y Q M P E 3 456789: '(;)*<  BCDEFGH R R   T  x  UV - . /WX ' ( ) * + , !" % hijklmn"/-. o n Z s W p g f H [ t h Y r J a O j T F I Go U ` | X q z { \ u _ w L l v e d C D ~  I  J  K  L  M  N  O  P  Q R ! S " T # U $ V % W & X ' Y ( Z ) [ * \ + ] , ^ - _ t W f g h u . ` / a 0 b 1 c 2 d 3 e 4 f 5 g 6 h 7 i 8 j 9 k : l ; m v w b c:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ [\]^_` abcdefghijklmno{|}~p qr  s t u v w xy z  6 7 8 9 : ; < d e^*@'eU]M+3!%!!^563d <,@)]oK_xL  +73"&54632EQyk*"-7!(5#+$=%")6b$@!]oL +3!3'$J#JG@Df   eoK  p L +37#737#73733733#3##7#37#Q7t "{ :j9a9i9u "~ 9k9_8T`"`eqffqe,q#$*1w@&1 JK PX@!oWg]qL@ Wg]qLY@$$ +7&&'57.5466773&&'76654&'3V$%f:#+G*3232>54#""&54>32'2>54#"DF/O:CI0Ps  FG1N8CI0N3  RJ,eZ9NM+e[:6y'O$_S_"I0d#'_(9"" 1 6n#*) `YKd,>@D[.*D(Jd"#E(Gz20 3&0!. 4+-b @]oL +3b#J$b@oL +&&5473m%$~xGn?@P|NwLBb.@oL +>54&'3HGn?r%$~xNwLB@P|T60+''7'777'^,`e*}7 NPy-tU|5oT &@#Ue]M +3##5#5353]kkkkt@U]M +667322E#;4 5~7.I@U]M +77!zz @_xL   +"&54632X*"-7!(5 +$=%")6@oKpL +#3,u6 !-@*_wK_xL!!  +"&54>32'2>54&#"e`(PvM[h$KwG0&1%  |rbQny_Uz1Sek/626Wec%7:Y !@ JoKpL  +3667'%3X &_AzS  54&#"'6632!:D("$D.G2vMFY*7_<h3K;%&$&c+:2P,@g]2l+J@G$Jg_wK_xL ++ +"&'532654&##7326654&#"'66328a$)`-GY5IC$*Q4&*,G>0kOccZT6L> :;$0l1+( d(]FJg GD9gA .@+JfoKpL  +37!733#37>7#x_SS "r?u y<3 0 '!D@AJg]oK_xL !! +"&'5326654&#"'!#6632:a$X083eq+ 6X3? ';&6 &f)TAJ{I+30G@D Jg_wK_xL! (& 0!0  +"&546676632&&#"36632'26654&#"hi&G11zR;3dtJ5IW7##"&54>3226676654&#"!@;!6L2 F2URN("+lR(aY:o}G/+2y.  )4/E#*, , -@*_zK_xL      +"&54632"&54632*"-7!(5*"-7!(5+$=%")6m+$=%")6, *@'a_zL      +"&546326673*"-7!(52E#+$=%")6;4 5~75cq0+%%5%NcFu5/@,eU]M +5!5!5jjkk5cq0+7%%55N؉uFM'?@<  J~_wK_xL#!''%( +76676654&#"'6632"&54632 6<1,"#G,--m?Xc'B*"d*"-7!(5EZ)!, l$VL2G8"&+$=%")6-N@O@# E =>JKPX@( g c_oK _r L@&  g g c_oLY@BAIGAOBO;931+)! @@ +"&&54>32#"&'##"&54>3232>54&#"32672677&&#"rNL] ?Z9': :.8K#B_;6L4 -!syc\2nY=f4/q@'1  #4"[Y^rx=;oX4"&!'GP3aN. '@M'csZpEsE[I;l#7=&8,@) JfoKpL  +#3#'#3'&&7#<vH T  6)<5c!9@6Je]oK]pL!! +332#32654##32654&##f|RJ1:JOI5ASJcX7C,-QJUI^ E5Qg1+1C/74&)<7@4  J_wK_xL  +"&54>32&&#"3267B;Z|PD_/:"I- )@&e]oKpL  +3!#3#';||< >@;  Je_wK_xL    +"&54>32&&#"32677#7!D|5jgk]8$H+Ba@ DL% O1m [J0{8]p8PS~ '@$foKpL  +3333##;;AA64 "@ JoKpL  +#77'7![bJ<]bLV((VV(2(Vc.Q(@%JcoL  +"&'532673B*'0= {|;@I{j %@" JoKpL  +33773#KLʰގg=5f!"@oK^pL +333}}u'@$ JoKpL +3333#>7###  ϗG F6R"MK)IV)$@! JoKpL +333>73## H GCHR6->A<-@*_wK_xL  +"&54>32'26654&#"E-]b,[W:`9=<.O9 B {TQyWOSfBO5^yEGJg +@(e]oKpL &! +332##32654##Wi/RXL5P=CR_F4^>Up7zB:X3226654&#"W -]b0cL|:`9=<.O9 B{TQy\$SfBO5^yEGJH 3@0Je]oKpL ! +332##32654##k}ZCe::T&@G`$\hUk89P'7@4J_wK_xL'' +"&'532654&'.546632&#"6Y,V-1C0&8$ ҚRO!G"6Z"'@$JoKpL"" +333667336673#&&47#p"  $ĩz&\''Yp6=)_"6E+:.PB &@# JoKpL  +#373#9tKTuU ["@JoKpL +333:s?:!GJ %@"]oK]pL  +#7!7!!{#b}c}b"@a]oL +3#3iihgfglX@oKpL +33jm6b]"@a]oL +73#73Chi纞gg'dD@Jt +D73#.HmU05bE&dD@U]M +D7![DD^a -dD@" JU]M  +D.'53.( ^47 "M% ,A,%~KPX@ J@ JYKPX@_zK_xL@!rK_zKpK_xLY@ %%  +"&&54>32373#7#72667654&#"(F,$B]:4AqtnK4%$ /# 'WHCk@,$FG$-w0K+$.#-+FV+V'(KPX@ J@ JYKPX@qK_zK_xL@!qK_zKpK_xLY@" (( +"&'##336632'2>54#"*4Aq>2'G,$B]S/#@$2 % ,$F56!2'WHCk@w+FV+V4OR'/,,7@4  J_zK_xL  +"&&54>32&&#"32679\6&JlE1M"-3 /A",(%?"#N (YHIf:p El9//x,n(KPX@ J@ JYKPX@qK_zK_xL@!qK_zKpK_xLY@#!((  +"&&54>323466773#7#72>54&#"(F,$B]:18%p K "2$ /# 'WIBj@."%0G$-w5OQ'/+FV+V,,%>@;Jg_zK_xL#!  +"&54>32##326732654#"`x'MrK[\2/+F0+YmUK35) hkEd;TAVh ,4oF5#."<"K@HJ_qK]rK_tL "" +"'53267#?6632&&#"3#3"- dPY cP"9'"kki -O v (+G))cO m ' p2R1 A,&6KPX@J@JYKPX@"_zK_xK_tL@&rK_zK_xK_tLY@('0.'6(6"!&& +"&'532677>1##"&&54>323732>54&#"=P%&U/3@ D3'C)$B\85=qwKk/!$/#%/2%"1*WECk@+%FVc*]/JT%'/+FV+++)'@$qK_zKpL$) +33136632#654#" J1FG AC5"5' 060%.UH$4?#<9`:? -@*_qKrKpL       +"&546323+/*,+ttf!*,!'0"@ >@;J_qKrK_tL      +"&54632"'532673 */*,+3"- | -Of!*,!'0 v (+G2R1i)@& JqKrKpL +33373#'HݨY;$B#F@qKpL +33V,*V JKPX@_rKpL@rK_zKpLY@**$$%$ +333663236632#654#"#654#"tp  S98> V9DD AC0"5( /C0"5' 0"e1>;41>UH$4?#<8_;?#<9`:),LJKPX@_rKpL@rK_zKpLY@ $$ +3336632#654#"tp  S9FG AC5"5' 0"e1>UH$4?#<9`:,,-@*_zK_xL  +"&&54>32'26654&#"=_5$HmI_p"Gm>)9'!2  3^AHc8rfE~b9xBi;)7-HR%Z','l@ JKPX@_rK_xKtL@!rK_zK_xKtLY@!'''$ +336632#"&'#2>54#"!pL5'G,$B]:26 #/#@$2 %S#:'WIBj@."(B&]+FV+V4NR'/,A,*uKPXJJYKPX@_zK_xKtL@!rK_zK_xKtLY@$"**') +7>1##"&&54>323732>54&#"$  D3$C,$B]:1>q#1$ /#$20 "1'WHCk@*&F]5OQ'/+FV+++,iKPX@ J H@  JYKPX@_rKpL@rK_zKpLY@ %$ +3336632&&#"tp !T5  7W4"e4;WV ,%7@4J_zK_xL%% +"&'532654&'&&54632&&#"5M"%N)#6 237nb/X*0A & *1A} y @4UYiD8^`.f@ JK PX@n]rK_xL@]rK_xLY@  +"&547#?33#3267@N8J`@_8%C 7GH)stp  n 6K"^KPXJJYKPX@rK`xL@rKpK`xLY@  +"&546733266773#7#GD>C5!6( 0tp  R UH9'#<9`:e1>2:" !@JrKpL  +3336673uC  "CA"=G"%'@$JrKpL%% +333>733>773#'4667#Vqk r"(O.=2 "F)><<>;7D" &@# JrKpL  +#373#'1n8ww= ;"0@- JrK`tL  +"&'532677336673" .< P ,wu6*""PC)SO" %@"]rK]pL  +#7#7!3nXXrbrb+7@4Jgc_oL*) ++ +"&546776654#7267766333ZLf;E T_)%- E6)) D5Z  Dp)/KLn*66 7& W nI0K'PX@ qKtL@ ]qLY@  +3k(bh+6@3Jgc_oL+*%$#" +566776675&&54677654˜3"#1%2 E6))$#ZLf;E T_n*66 7& W nD5Z  Dp)/KL5 <dD@1JHGWg_O$$$" +D&&#"56323267#"&%3<2K;/%4=2K;- "q5  "q5 K " *@'a_rL       +"&546323!(5,*"-}vM|%")6+$=#P!e@ JK2PX@g]oKpL@gW_OY@ !!%' +7&&5466773&&#"3267;J:nP\6-3 /A",(%?"G, g[U[h MM p El9//x^^ =@:Je_wK]pL %# +#76677#7376632&&#"3#!,> ^^t`5]"7<%.  6&@x <:3ky^gq'-pk)1B8|G+@@= JHGc_rL! '% +!+.# +%'#"''7&5467'766327'2654&#">18)=G> ?H>23->I? ='77'&66|= H> ?F?35,=B6&'66'&6+v>@; Jf  eoK  p L +37#737#73333#3#{{{`^8c{{{lWCWm WCWlIKK'PX@]qK]tL@a]qLY@ +33kkkgrr 2>:@79,J_qK_xL" 22 +"&'532654&'&&5467&&546632&&#"6654&'6Q"W/0-#+9?6-6_=1Q&(D+'(*v:$;g)-)) m"!G11F22E$^ 4^8D17K'5 *+ ,(m  3dD@(W_O      +D"&54632#"&54632#'#$##'#$$m%(#+%(#+1$=edD@Z.:/;Jgg g W _O&%8620-+%=&=$$  +D".54>32'26654.#"7"&546632&#"3267Pc67dNLe96cPRP-Pm?VNMgfe0\CA:2+;A9B92 6cPLe96cPPc6@NY?nT/NYYNJ~gCg;CUIMR E Jm#K&PX@ J@ JYKPX@c_LK&PX@gW_O@+~~gW_OYY@## +"&&54>32373#7#72>54&#"0(A-*KMH0! &m:0!ME-,-J!24/F#6#,2  0+7'57'57c]Bvc]B, L2 L5y%@"U]M +#5!5kk.I1$2;idD@^-J ~g  ge W _ O%%;953%2%210/.(&$$  +D".54>32'26654.#"'32#'#532654&##Pc67dNLe96cPRP-Pm?VNM6RL0t[_>2''#,1 6cPLe96cPPc6@NY?nT/NYYNTF@/7 ¨' # WgZ&dD@U]M +D7!Wbb'9dD@.gW_O  +D"&&546632'2654&#"4N--N44N,,N4 ,, ,,+L11L,+M11L+](#$))$#(5r 1@.ee]pL   +3##5#53535!]kkkkkk8U2@/  JgU]M$' +776654&#"'66323802*21$Q5=G>,?Qk'1(M>/*:4!.bHT+M@J$JggW_O ++ +"&'532654&##732654&#"'6632%E>"#2>,(0.(#J,2=>,(#7X ^NI/33  -1>q^ %dD@Jt  +D56673q< )21^ U#(,(Q" HK/@,J~]qL&" +#"&&54663!##\)>\37cB'OQ .l[_n.@4 3+:dD@/ JW`P  +D"&'53254&'73( !2&/Z(IR(K# (%2D[K &@# JU]M  +7667'73) @2e[5(QyTSmPKPX@c_L@gW_OY@+"&546632'26654#"AC*S=F<)G- %!mJB:b;O< KC*P-B 4.B6,  0+%'7'7'7'7K]BxcN]Bxc,L2 L2 G'o'{~'wb~3+b3+GQ'm'{~t`~3+`3+/<'u''a3+a3+B#" 3+8&$C3+d&$v3+b&$Jf3+|&$Qt3+Q&$jD3+8&$O3+?@<ee ]oK] pL +#!#3#3!7#3#<!'q$k>'||})%<&&z#@&(Co3+@&(v3+@&(J>3+@&(j3+&,C3+&,vb3+&,J3+&,j3+ 7@4e]oK]pL ! +3#7332#'326654&##3#=ED@]-4Rj4I@8%tt#|+m}WROK|&1Q3+<&2C3+<&2v3+<&2J3+<&2Q3+<&2jw3+I? 0+''7'7KIIJ?IJJK1$.<@9 -J H_wK_xL&%%.&.%+( +'7&54>327#"'7&&#"26654&'|K;0-]bY<3J9,[bW="#'1Q9Uo7 A:X{?H@E"!J_qK_xK_tL86&$  ?? +"&'532676632#"'532654&'&&54676654&#"1-+ |}gw87 )0ro[6A"2-&&*8- &')(/| /Sv (/MjgXI?I  B2Ngu!":&2:&$27S/,A&DCb,A&Dv,A&DJ1,G&DQ?,A&Dj,AE&DOx,O,/9IXKPX@  ",)#JKPX@  ",)#J@  " ,)#JYYKPX@%h  _zK _ xLKPX@0h _zK _zK _ xLKPX@7hrK _zK _zKpK _ xL@B hrK _zK _zK  _ xKpK_ xLYYY@#;:CA:I;I7520+*'%  // +"&54>323736632##3267#"&'#7#32654#"267654&#"CT$C\72<\ M)OU.;%S!&Z05F\FUK36*+? "."$ eaHh<)'F,TAVh':o.G$-F5#."..'/+FV+/',,&Fz,&HCV,#&Hv,!&HJ%,&Hj/&'C&'v&'J&'j{#5#1>@; J Hg_xL%$,*$1%1 ## +"&&5466323&&''7&&'77'26654&#"?b7;pN2=q+b :!;t%^(!GnF$5#%)6& +[JMP%)O@H7  [$@J44yJQn?n:Z."0:X.'-N&QQF,&RCV,#&Rv,!&RJ%,;&RQ3,&Rj5lU A@>geW_O      +"&546325!"&54632'(())(())#')!!)'#kk#')!!)'#&<$0<@9 .J H_zK_xL&%%0&0&*( +'7&54>327#"&'77&&#"2>7645ZE:#$HmI@/"G) "GmJ8- $1M"025H4IHc8+634KE~b9 '@I! m)?I 6K&XCg6K&Xv6K&XJ66K&Xj;&\vv'+B@?JqK_zK_xKtL#!++&& +33632#"&'#2>54&#"!ԓ  ?KDV=\>2> #/"% 0"! LSbe3234677#73733##7#72>54&#"D[=]>2;KL{nG/  #&; % be7ve?* 4,aOOaG 1w,DL #+@a3++@m&(Lr3+,&HLY@&(ML3+, &HM3@&(N3+,&HN@&(P,,.8T@Q#$Jg_zK_xK_tL641/(&! .. +"&54>32##32673267#"&546732654#"`x'MrK[\2/+F00; &2:3(BUK35) hkEd;TAVh ,4o &B"V4+-?F5#."<_&(KC3+,F&HK*<&*J3+ A&JJ.<&*M3+ A&JM<<&*N3+ A&JN<#&* A&J&:&+J3+)&KJְ3+;@8  f  eoK pL +3#73733733###37#nVWWXnAA\ a____a4X#"f JKPX@!fqK_rK pL@fgqK pLY@""$& +3#73733#36632#654#"|ON I1FG ;=4!7' *HaOOa.K%.UH$4!#<9`:&,Q3+&'Qm&,L3+&'L&,M3+&'M&,PJ?&LP &,N_3+.&,-i&LM)c.&-J3+&)J#&. S#i&N :i"%@" JrKpL +33373#'tߨY;$"x?#&/vd3+&OvIְ3+#&/ &#F&O =&/% а3+&O%X&/N 3+&ON 3+ *@' JoK^pL  +37'737322lG4E4*c:Q&cR}d $@! JqKpL  +37'73702mS@4qCc;c=&1v(3+6&Qv#&1 z#),&Q =&1K3+Y&QK=&Qf. <@9 J IdoKpL   +"&'53267##33>73c.(6= G @v*1->ACK6me),#m@JKPX@_rKpK_tL@ rK_zKpK_tLY@ ## +"'53267654#"#336632 3"- K5"5' 0to U9FG M .P v (+d#<9`:"e1>UH$44S0<m&2L3+,&RLY<&2M3+, &RM3<&2R3+,&RRW<'@JKPX@#e _wK _ xLKPX@-e _wK ]oK _ xLKPX@8e _wK ]oK ]pK _ xLKPX@6e _wK]oK ]pK _ xL@3e _wK]oK]pK _ xLYYYY@!''  +"&54>32!#3#3!'267&&#"E-]b#.!'- '_*.O9 B {TQ||} 5^yEGJ,Y,'1@KPX@ %J@ %JYKPX@#g _zK _ xLKPX@-g_zK _zK _ xL@8g_zK _zK _ xK_ xLYY@32:82@3@/-*(#! '' +"&54>326632##3267#"&'32654#"26654&#"Yn"FjH4M#`@\[3.+F0+X;5[RUK36*'6!% .$ pdHb8(&$*TAVh ,4o#$!&F5#."3+ &]K7@4J_qK_tL  +"'532676632&&#"#3"- dP"9' ! .P v (+pcO m ' 2R15"I@FJe_wK_tL "" +"'53267#?6632&&#"3#F3"- [R\ cP"9' "kk` -O v (+I')cO m (p<2R1 (2V@S.J  ~gf pL *)$"((    +56673&54632#'#2654&#"3'&&'#w;<=e C64HLS6   X6%!  6>>5-I ;,Z "8HKPX@ / 5 J@ / 5 JYKPX@6 g h _zK _ xL@> g hrK _zK pK _xLY@.:9$# CA9H:H4321-+#8$8""    +56673"&54632'2654&#""&&54>32373#7#72667654&#"L<<>K6CC64HH4(F,$B]:4AqtnK4%$ /#X6%! >66>>57>Eh'WHCk@,$FG$-w0K+$.#-+FV+V&vi3+,O&v91&v3+7&v#&6 #,&V q^0dD@% JU]M +D5>73#&&'q653a-7^ 57#T .'^1dD@& JU]M +D&&'5366733a-7j64^#T .' 57o^&dD@U]M +D7!o.^gg^1dD@&W_O  +D"&&547332673-;EUK&1\ ]^'=! =#OVf" 'dD@W_O   +D"&54632 */*,+f!*,!'0]E 9dD@.gW_O      +D"&54632'2654&#"6CC64HG5]>66>>57>E8dD@-JW`P  +D"&546733267>2:;.a#: &4+1C;#Vo]4dD@)Wg_O"""" +D66323273#"&&#"oG3 .'TG4 -' ]OH4PG4q^9 9dD@.JU]M    +D5>73!5>733(( *43(( *43^ 46(,( 46(,(^ -dD@"JU]M +D5>73  >&^?? '\/m6F !MdD@BJWe_O !!    +D56673"&546323"&54632;! =""&!$#"&!$# V !N'9%(#+%(#+C&$ S 3+J> 3+$&(nS 3+$1&+pS 3+$\',S 3+$&2TS 3+ ('<S 3+$/'Se 3+(F&T8$c%>;K2PX@]5K6L@]5LY@ +3!#}|@(J=+<#>@;e_=K_6L  # #"!  +"&54>32'2>54&#"'73R/_`.\X7Q5A>:T5E XK[}H5]wBCT;bu:CS||,. :JK2PX@ 5K6L@ ]5LY@ +#3#&&7<mD $ 3])&SRu01' eK2PX@ e]5K]6L@ea]5LY@   +7!7!7!{XF@N||||}}<2>K2PX@]5K6L@]5LY@ +3!## }}6Lg3A P@ JK2PX@]5K]6L@a]5LY@ +#7%'7!!! #vr|}RZ7[<<"z@ JK2PX@%WW]5K ]6L@#UgW ]6LY@"! +7.5466773'6654&'Yg,[eUg0Z@Oa5U[6: mGg9dAXXBf<n-\U2DaR1B;WU#NK2PX@h5K6L@h5LY@###!! +!7#"&&5467733333266773##.Qf/.167PP)@- 26 -5W30  0({=:s&,j3+[&<j3+,^&{S! &S)&S&/w&S:FF&T,^,$4KPX@ !JK'PX@ !J@ !JYYKPX@_@K`6LK'PX@8K_@K`6L@)8K_@K`6K_6LYY@&%/-%4&4$$ +"&546632366733267#"&'#72676654&#"ATAtL58|1! *.> E(5  /" `fi`0$, vC t &+ 1wG7@'/*FS(]Y,L@I *Jg_?K_6K:L'%!,,,# +6632#"&'2654&##732654&#" xrdmZR;H6`K5D8<;7-4>$#5U6hg[PV` SC#UN2 ]O80*vA>!%2Ey:""@ J8K:L+6673366773 ,!D &y05>{>'P##S&XCY"/9@6*J_?K_6L$##/$/ ""+"&&5467&&546632&&#"'26654&'L^,g *:c<>_*:$E#+$ 4>DI"4+6654&'&&54667##7!&:+FIQ\2t}fO!0'"8!0+&E ^L\GmYR}dV++1$4'1N(),xJKPX@_8K6K:LK2PX@8K_@K6K:L@_@K]8K:LYY@ $$+654#"#336632v5"5' 0to U9FG t/#<9`:"e1>UH$417'9@6e_?K_6L #"' ' +"&&5467>3236654&#"267#FT% KsW]^ Iva,B,@ :c>)t=gSrk,f>dZ&@"&/sDpsM<)1/?"+@(J8K`6L +"&546733267AMKL*$B 7G "a # n i"$KPX@! "J@! "JYKPX@~_?K6LK2PX@~_?K6K6L@ ~|_?K6LYY@ $$+"&''&&'#'&&#"'6323267:9  x+   ,2TR 2 - CBbE>-. x \V:)r 2/" :JK2PX@ 8K6L@ ]8LY@ +336673vDAU">MÍx-G36@3 Jg]7L33'%$"+6654&'&&54675&&54667##7!#"33#"&8,JDbO.5*G-#9p %MB)q2"aZ+,"8!0+&E"[?V] 8',9# mg 3&PgE2'($3'1N(,,R."KPX@ J@ JYKPX@]8K_6LK2PX@]8K6K_6L@ ~]8K_6LYY@ +"&5467###77!#3267@D6\]u`Au5%: ?;  NH(p# j ',!<@9 J_@K_6K:L!!%$+>32#"&'2>54&#" o;iXdg=rQ*@ !0  +4RyAu_b_"&K)]3LP+0MO+,G,#)@&J_@L##%-+6654&'&&54>32&&#"&8+CL$HnK1L-6-B#0'"8!0+&E]Q:wd=p <\/0/$4'1N(," 0@-]8K_6L  +"&54663!#'26654&'#"`tJl%@`;)9 :J# qhcWmM2KRG,x?f: 2Bi8d."5@2J]8K_6L +"&547#77!#3267@N8]m8%C 7GH(p  n :<"$@!8K`6L +"&54673326653ia??E,E& #Dq gS%) LSKrC,,%7@4JH_@K6K:L#!+7&&546776632>54&#"3Xq^R`9A)!6aZ\bRh/H9H"" uemES9tF5;`br`g[_ Ll7&1'/g,"KPX@!J@!JYKPX@_@K_:L@8K_@K_:LY@""%$$$+'&&#"'6632733267#"&''84=> $ -?? % t EOY!tFL:1@.J7K8K^:L+7&&546733>530md??-*=Q**O]0 gM%) &+r ^TjC,"/:@7-J~8K`6L+)#" //+"&5467332677332>54&'3#"&'VTF2$:!&& 0! :vY;> L mWcO5y|:'-@:!5Xj5(D G!zp6--6/&j:<&j,&RS:<&S,&S@&(j3+R&KPX@ J@ JYKPX@ e]#K_+L@$e]#K$K_+LY@&& +"&'5326776654&####7!#322" ( &rF}v[] /Q | !."  L~~YH:AR&J&`v3+<"F@C   !Je_*K_+L ""+"&54>32&&#"!!3267B;Z|P>e/:"L*6P8CI(T)\ ?u]5z0Q0|JM&6,&,j3+c.Q-"+KPX@ JKPX@ J@ JYYKPX@ g]#K_+LKPX@*g]#K]$K_+L@(g]#K]$K_+LYY@+)%#"" +"&'532667667!32###%32654&##($ (&E,:!Ti2||('!CR:G;//5 |77D2X9|yLLy+U]#C1$(v3@0h#K] $L$! +333332###%32654##:;:*woCCt>D:^5iX}z<|B/OR-@*e]#K$L%!+3#7!#32#7654&##}n_` )1.jFL~~XN9 #&v3+&$!3+0 )@&#K]$L +7#333#-}}-L68$B 1@.g]#K]$L !+3!#32#'326654## !~q'14=^5|oYxx|2Sc%>`0 3@0Q]#K]$L  +367!3#7!3#`F?M@v}[G--cb?MNnNC@(,@) J#K$L+#333##=.GG䐚JJ}MNN_^J+P@MJ~g_*K_+L%$ +++"&'532654&##7326654&#"'6632Ia%.e0J]RJE>0U6...W+59yXB^2rYKL 5>1'v*(") f%*.K-XX V;ky$@!J#K$L+3333#667'H uG  &a%6P,X2&$|3+ %@" J#K$L +333#G䐥JN_pKPX@ J@ JYKPX@]#K_+L@]#K$K_+LY@+"&'532667667!##($ (&E,}('!CR |77D6LLy+U]#u0+<2lg3<&RZ70@- J#K`+L +"&'5326736673v83-1K  *I]  6" *' 5 Hc2<q;0 MK'PX@R#K^$L@a#K^$LY@ +7!3333-#}}~fFLZ+@(Jh#K$L%#+!#"&&547332673z:$Y-,Q375K&G#DE:   @@6 %@"#K^$L +333333}}}}LL60SK'PX@R#K^$L@a#K^$LY@ +7!333333-}}}}~fFLLR 1@.g]#K]$L !+3#7!32#'326654##|A:!~q'14=^5L~oYxx|2Sz 6@3h#K]$L    ! +3332#!3%326654##:~qi"4=^&oYxx6|2S +@(h#K]$L !+3332#'326654##:!~q'14=^5oYxx|2S E!F@CJe_*K_+L !!+"&'53267!7!6454#"'6632;^)2Y&Ui~+E-'/n:9X{ \Z| x@v\6'KPX@!f_#K _+LKPX@%f#K_*K _+L@)f#K_*K$K _+LYY@!''  +"&5467##33>32'26654&#"pzA;W[z})UQ3V366)F3: {  POyYNSfBO5^yEGJj8@5Je]#K$L'+#&&546633##37#"=-3@`헕:95)B=B=AI7>76632'26654&#"\n;Z<$mv1MJ-F0R7HI"Fl;#8 /'  ryIe~  'I< 4`T>yb:y@c2#('42;, ,,?@<Je_,K_+L! '% ,!, +"&54>3232654&#"2654&##py'LqKXmC3#42ib*/!+C0)-/7G3 sjD|a8LG=:  30.P1W""@*! ;1 ,+7@4()J_,K_+L&$+++"&&54>7>54#"'663232672V4!8C"0- ;">"$%c72S1 7H(/1'*R#)V D9-=( *hA6.=(o,9!.I@F &Jgg_+L#"*(".#. !!+"&&54663236454&#"'6632'2667&&#"I^,^L4%b[ t L_UPx>b7 +nY+0,,H,GKPX@'5 6J@'5 6  JYKPX@%   f_,K_ +L@-   f%K_,K $K_ +LY@!DCBA@>:831,*%#  GG+"&'7326654&#"566323733>32&&#"3267#"&5465##7#8!   .> $+QgQ11MHlH!   .> $+QgU//JGl uEl9//wkh Cl>uEl9//whh Bh< ,)J@G#Je_,K_+L ))+"&'532654##732654&#"'66328`![54JVV=>?!*!Q(#0j=8Y3I6)4 y)9g$k;1;> 5.Rd6K"X6r &X$ c" %@" J%K$L +3373#u6רꇥ}9" Q,zKPX@J@JYKPX@_,K_+L@_,K$K_+LY@ +"'532667>32#&&#",*"0@bJ2Zo\(1%!,? y/N.EfB! .ZC2XC&"'@$ J%K$L+3333#667###su<ύ 5"}&Fo)@ W" '@$f%K$L +33373#7#u-,t/0",,R),Q',S,,FV,P;"\,'5@2 J'I_%K'L+7&&54>773>54&'3gl"M}\,,ejGc/DF,<#*.;!*) |Y6p_>{[1jaD ^F*>D2C.?B-?D"[4<K"$nK'PX@ #J@ #JYK'PX@R%K`+L@b%K`+LY@$$$$'+7&&'##"&5467332667733267x/R5GF>C5!6( 0O  C /,6UH9'#<9`: PB"+@(Jh%K$L$'+!7667##"&546773326773; F,CJ:2= t- %UH9v#>ec>4x"*lKPX' J' JYKPX@%K`+L@%K$K`+LY@%# ** +"&547332667733266773#7##"&'#DD AC0"5' /C0"5' 0to U98= W UH$47#<8_;#<9`:e1>;41>4<x"5yK'PX@ 4 J@ 4 JYK'PX@ R%K`+L@ b%K`+LY@55$$$%' +7&&'##"&'##"&5473326677332667733267/R58= W9DD AC0"5' /C0"5' 0O  C 1,8;41>UH$47#<8_;#<9`: -j""?@< Jg]%K_+L"" +"&&5477#7!6632'2654&#"eGV& +>04!UX2rL.. )#+ *H."6pU?0[:g/ ! %4"$p JKPX@h%K _+L@!h%K$K _+LY@$$  +"&&54673663273%2654#"HS#B02CV1itt`#,=$" *H- 11NC3[: "],%:  3" 8@5 Jh%K_+L  +"&&54736632'2654&#"HU& B04!VW2rL..!(", *H."64U?0[:g/ ! %, F@CJe_,K_+L   +"'53267#736454&#"'6632J3<%1J1!-'$Q57Z7A { 2Cc 4)l,`O`^,$sKPX@!f_%K _+L@)f%K_,K$K _+LY@$$  +"&55##33>32'26654&#"_ie0u-^EhFaf!Dh<"5$- ob"@c9tdE~b9xBi;)7-HR%Z4"'KPX@ J@ JYKPX@ g]%K_+L@$g]%K$K_+LY@ #!' ' +"'53267667&&546633#7#"37#"@,  &!,@l@s, $>->$0" y*) 6/AR&)>" ,9)%!,&Hj#.@! JKPX@+n f _ %K$K_ 'LKPX@* f _ %K$K_ 'L@( f  g$K_ 'LYY@&$ .. +"'53267654#"##73733#36632 3"- E4!6( +{NN I1FG G .P v (+F#<9`:HaOOa.8%.UH$44S0 &v,,"F@C   Je_,K_+L ""+"&&54>32&&#"3#32679\6"FnK1M"-3 ,E-(%?"#N )YHDh>p 97c 1-x ,V?L&'j{@M*,.<K PX@$%J@$%JYK PX@!g_,K _+L@,g_,K_+K _+LY@0/64/<0<)'"  .. +"&&5477&&#"#"&'532667>326632'2654&#"%GV& , (0#.I?"-C5!6( 0to  Tw%{/ UH9'#<9`:e1>4]a%@"]#K$L+3!73# 9}ʗFKPX@#K]%K$L@]%K$LY@ +3373#t9Z"WZ&:C3+=G&ZCZ&:vh3+=G&ZvZ&:j3+=G&Zjf[&<Cm3+;&\C*E@U]M +77!ppE@U]M +77!ppES7dD@,eU]M +D7!7!MTZDDDD8&@]oL +'6673<F#n2 4~8;44"@]oL +667342F#;4 47t@U]M +667322F#;4 47m@J]oL +&&'73 3~9 @18$@!]oL    +'6673!'6673F#n2F#n2 4~8;4 4~8;44$@!]oL    +6673!66732F#2F#;4 47;4 47t*@'U]M    +6673!66733F#2F#;4 47;4 47] %@" JqKpL  +37737'u}EJvv,0@- JqKpL +377777737'7'yA+ A. vogvvgovD\ @W_O   +7"&54632;QQ;&@&RHSTGD8SH &'$8!1AO]KPX@2    h g_wK  _pLKPX@6    h goK_wK  _pL@:    h goK_wKpK  _xLYY@;QPCB32#"XVP]Q]JHBOCO;92A3A+)"1#1!!  +"&54>3232>54#""&54>32!"&54>32%2>54#"!2>54#"DF/O:CI0Ps  FG1N8CI0N1FG1N8CI0Nc    RJ,eZ9NM+e[:6y'T]!y:M 6 L=B,d5M&=0/N,2$D"> ~wW VmICVW;<~<,8v@s  J~ ~g g  g W _ O.- 42-8.8'%, , +"&546632&&#"32673"&546632'26654#":K*Q:-"%3!/sd;I*Q=?E(Q6 %!oCB ` ]QUIAZF }(211_iL5 $%  /3]@Z Jg  gU] M00"!030321*(!/"/  +336673#%"&54>32'2>54&#"7! ~ B~ An;I,F3:I-F* &k;76HR!͆D@&NB)JB%L@&P 00!110\\jC@@ J  U]M +33#5467###!#5!#E^^a[@e5`e fj`/ (*66'P&JK2PX@_=K]6L@a_=LY@''&)+#73.54>323!76654&#"3!2SzR^~@&>G!_THD9M.GA]>-c_M-EtILrP62bMR0P_0}D5;"D@A"JgeW_O  +"&&54>32!3267!5&&#"8Tt;.K\.JuDlN-IV"#:T#L41HN~HHhD C|U%<6%>%>&"GL'u'{*_3+_3+/e&u'*`3+`3+8`''(*_3+_3+M6'X'*^)~^3+~3+$@ JK2PX@5K^6L@b5LY@ +#73%3&&5"&!"e/-+)%''%U/-+)%%'^D0C.B,A*@ '%'NK PX@4 1 p(&"%%&p 5 32e  U76  g  g=<e;:98!g#!?$>"&!"e/-+)%''%U/-+)%%'^D0C.B,A*@ '%'NKPX@4 1 p(&"%%&p 5 32e  U W76  g  g=<e:U;98!g#!?$>"&!"e/-+)%''%U/-+)%%'^D0C.B,A*@ '%'N@4 1  ~(&"%"&%~ 5 32e  U W76  g  g=<e:U;98!g#!?$>"&!"e/-+)%''%U/-+)%%'^D0C.B,A*@ '%'NYYY@}}wwssoobb^^KJ;;-,!  }}~w|w|{zyxsvsvutororqpnlhfbebedc^a^a`_][XVQOJUKU;I;H><7631,:-:'% +!+   E+5#53%53!5353#75353!53"&54632%"'5326553%32#%2654&#"%32654##53!53%32654&##53!535353!533!53!53!53_^5`6B>>BB>>p =6T57,5." ""  +655B$"5`6_5`6^Q^6^6666^6^^66㄄QBCPPCBQ22- )3"',/3--33--3~򄄄5__5555555)d+A@>JHU_O! '% +!+%)+ 354676654&#"66322654&#"6g!++\P*X"(!>!& 8))((6{">1CJW"8&#%%#&)K4"97C]@ZJ~~ g_?K_ 6L888C8C?=3210*(#"  77 +"&&54676654#"566323267.546323#6654&#"!CS&  9$53  7XZq5y`IZ)IA.Ltx# 9 (A$% i4). w:W1^fApFpIl@  9=+##6Zo@ JK'PX@_5K6LK2PX@5K_=K6L@_=K]5LYY@ %&+336676632&&#":s? E"C+# 2H0954&'!VT,#`!w @`@;> L"&&  .' mWA3H(p2 ={f=6--6t@:CC!-M`3<~:'-u&0vP3+V&Pv[8&$C,A,&DC 9dD@.gW_O      +D"&54632'2654&#"G6CC64HG5>66>>57>E<n(:@7 JqK_wK_xL" ((  +"&54>326673'26654&#"E-]bLm &_D ,[W:`9=<.O9 B {TQ50E2 Sc'+WOSfBO5^yEGJ,t(:@7 J_zK_xL#!((  +"&&54>326673'26654&#"=_5$HmIk8)$-M<"Gm>)9'!2  3^AHc8GP. 6O;$E~b9xBi;)7-HR%ZE 1@.JqKoK`xL    +"&54673326736673#lr`_\C5!6( 0 /"@hLUo  T UH9'#<9`:7 L0 7^=qe1>S>.@+  JW_O%& +7>54#"56632!.;B6* SH P.,-4 #@&(Co3+&C3+,&HCV6K&XCgT&(@%% J#K$L&&+3.6733>77>733673#&&'"  Z Cm(-}~B^nƣ:9;#9:'`²Hh@CBM"$(@%# J%K$L$$+3.67336677467336673#&&'  #H /X$JlJz3HXs/8w$N2tYG}`d/s1>@9@6fg#K] $L! +3#73733#32#'326654##>mml!~q'14=^5p^^pDoYxx|2S#(JK PX@'ng]%K _ +L@&g]%K _ +LY@" ((  +"&&5477#73733#6632'2654&#"HU& *su4!VW2rL..!(", *H.$6pbbpnU?0[:g/ ! %*KPX@' ( J@' ( JYKPX@" f_#K _ +LKPX@& f#K_*K _ +L@* f#K_*K$K _ +LYY@%# ** +"&5467##33>32&&#"!!3267RaA;\]c>e/:#K*7P5E;+P6/_ }  NQz2K(|KL,+KPX@( ) J@( ) JYKPX@" f_%K _ +L@* f%K_,K$K _ +LY@&$ ++ +"&&5467##33>32&&#"3#32678]6c0u-]KkD1M"-3 *?-(%?""O )YH"@c9p 9,n //xa 0@-Jf#K$L +#3####3'&&'<\!>Bg 344,L#4." 0@-Jf%K$L +#3#'##7#3&&'=A\'/r[ !"3+DB`dJKPX@ f#K $L@  U  e#K $LY@ +3333######3'&&';\!>BAg 3444,L#4.":@7J]%K ^ $L +33373#'##7##7#3't-|\ *3|0H"Pp:@7 J~]#K$L!+#667'7!#'&&####"7#*{!TEmB >4 =@*_GD CF\R&26&/R"1@. J]%K$L+#7>7'7!#'&&'#77#2Z-5%`  .#| -2 N[-733O?$Lq#&@@= Jh ]#K $L&%##! +333'7!#'&&####"#7667#7#;fB '1 =@(ah A~CF+I=&26$/-K""B@? Jf]%K $L"! +333'7!#'&&'#7#767#7#t-V  .$| -2 NP~0["ҟ33O?# +LqJcSKPX@(93-&#"SJ2HG@2(93-&#"SJGYKPX@1~Wgg W ]MK.PX@2~ggg W ]M@7~  pgg gW^NYY@QO-$%%!,b +&&#"#"&54667>54&##7326654&#"'667&'536632&&#"32632%CAYT4r\EFRJE>0U6...W+5*V62Q#&I3 .'BIrYJM.Rk=G;:.?&!" Q:=Q2$ OKPX@"$5/)!;OJ.HG@".$5/)!;OJGYKPX@+~gfW]MK.PX@2~~gfW]M@7~~pgfW^NYY@MKJH$%$!)R +&&#"#"&54676654##732654&#"'667&&'536632&&#"32632c%*P.PQemOGVV@<>!*!Q(#>" Q#&I3 '+8I6)4KR/1#"E !! LBJT )6g&k 0 &):I:3;= 5.DK"  WUs:<#9@6e_*K_+L## +"&54>32!4654&#"267!E-]b,[5><>cG?gC {TQyWOBO^|bX GJ,,"9@6e_,K_+L"" +"&&54>32354&#"267#=_5$HmI_p"Gmv"')9((;' 3^AHc8rfE~b9P,8B?5 ,0ZO@ JK'PX@_#K$L@#K_*K$LY@ %,+3336677>32&&#"> p9J8%  ,b&Q !O>Z1y&6 2E&,@)J_%K$L#,+3336677>32&#"uC  C1>/% "=<3F$ t Z&a E3+2E&b <&2\,,&R\I<08@5% ,JgW_O0.$" +"5&&54>7663276654&'#"'6632Q=io&NzS ;hm%MyT!.FZ)' )0H(,' '=9wHyS 7sLyR u;S#VyEBT,ML,7@4'#JgW_O&$ +"&'&&54667632'66326654&'#"'P`7oU/- S_5mUD %-/))(6u[T^ %%y]Q^ nD"5(&AO&J@"a|@yP/O0 A _ J~   ~gg _ *K  `+L$#][TRMKEC@?<:42-+#a$a#!""+663233#".#"7654&'&&5432"&&54>32&&#"32677332>54&#"'6632#"&' F5'EF* ':/.!9  /!Nj5)PyO3M60!$=-:3')) ,3K22#0#"S">^3.YU4X"R>9?% $!MKN]~Gn 3Xt@KOA@ n?rL\P)"&+5o#^|@yN.M/ @ \ J~   ~gg _ ,K  `+L%$ZXRPKIDB?>;931,*$^%^#!""+663233#".#"7654&'&&54632"&746632&&#"326773326654&#"'6632#"&'_ G4(EF* ':0.0 9  ">RfE{O+<.!%4(#')&8$8*4S1AxP8W'O=9>8%  "%8e^yU o -FM43?j@+. j*XDsX0!.#T&M3+BM&N<6@3 J_*K_+K'L%%'+7&&54>32&&#"32672ux;Z|P>e/:"L*32&&#"32674C^&JlE1M"-3 /A".(0O `^If:p El92, 3/v 0+'7'77'77''?X"a#Y>Y$b#$P<:*7*75310.,))'%#"  ""(+D6632#&&#"6632#&&#"!6632#&&#"6632#&&#"!6632#&&#"6632#&&#"!6632#&&#"6632#&&#"2205'% 2205'% 2205'% |2205'% 2205'% K2205'% 2205'% 2205'% Y+45*,35*,35*,35*,35*,35*,35*,35*D#,5>GVdD@K ;:10,('$#"75JeU]M???G?GCB+D'6673'&&'7'7667&&'5&&'57&&'7%'6676673 !/ '!40"U'"$P&X&)^$)^$&X&50(y"$P0"U D !-&X&)^$"U'"$P0(!5 !/ D D !$P0"U' !40')^$&X&0+%JK PX@+n~    h#K$L@*~    h#K$LY@++*)('!   +"&&54673326737#667'#3333RW!,'-7 9gXvG  H u|,F&  $ (35O+,P,X2&a%4<k 3#JK PX@)n h `$K  ]% LK PX@+n _#K `$K  ]% LKPX@* _#K `$K  ]% LKPX@( h `$K  ]% L@, h$K `+K  ]% LYYYY@!33210/+)%$  +"&&54673326737#7##"&5467332667733jRW!,'-7 9gnjY R5GF>C5!6( 0]{^,F&  $ (35O+X,6UH9'#<9`:K9@6fg#K] $L! +3#73733#32#'326654##nIGyx!~q'14=^5|JJ|LoYxx|2S8({JK PX@%nfg _ +L@$fg _ +LY@" ((  +"&&547#73733#6632'2654&#"GV& DMN14!UX2rL.. )#+ *H."6Nk9(Cz9(=!6X',.z@"! JKPX@_%K_+K'L@!%K_,K_+K'LY@..(&+$+336632'#"&'#27'76654#"!pL5'G,6&-O/26 #)P#@$2 %S#:'WI;ue#I3M."(B&]C3:$`1V4NR'/> -@*e]#K$L +3#73!#3#>JI?%=#|+||" -@*e]%K$L +37#737!#3#,DD0i+syjsE$v@JK2PX@#g]#K$K_'L@ gc]#K$LY@ $$+"&'5326654&#"#!#6632*I@%6P+GB$ 9*,,WF*&Ny  =iCPT|AiKFk@ "!I@FJg]%K$K_'L !!+"&'5326654&#"#!#6632@56?*,'ti#[_@p  9[15>"yy}b7ue>05@2 Jb#K$L +7###3333-#JJ.GG`fF_^}MNN<,DKPX@5 C J@5 CJYKPX@)f   Q _ ,K _$L@1f   Q%K _ ,K$K _+LY@DDA?:831%%%#+7&&55##7##"&'7326654&#"566323733>32&&#"3267->LT//JGlF!   .> $+QgQ11MHlH!   .> &"#CĿ eYBh<uEl9//wkh Cl>uEl9//J&[ ,&[0.@+ Jb#K$L+7##333-WJGaF_N<c".@+ Jb%K$L+7##3733p/D}9u6רJxC "4@1 J]#K^$L+3377373#'#7'GF&F hѣ; F$!JW<8U,}"4@1 J]%K^$L+3377373#'#7',u6+ A Z쉡=A%9"16i~R03@0 Jf#K$L +3#73733#3#o??AA䐥J |BB|N_c` JKPX@nf%K$L@f%K$LY@ +3#73733#73#}OO>רꇥ}9HaOOa R  +@( J]#K$L +3#7!3#t|4G䐥JL~N_$" +@( J]%K$L +3#7!73#h]46רꇥ}9p 00@-fa#K$L +7###3333-AA;;~F4<k"0@-fa%K$L +7#7##33733.~/0u-,ZnC"XX -@*f]#K$L +333!###;;,|AA~4" -@*f]%K$L +3337!##7#u-,:\/0"pN&z@JK2PX@$g]#K$K_'L@!gc]#K$LY@ && +"&'5326654&#"###!6632v*F @%6P+K> 9}}D.,VF+'Pv  >iBTPLAiKIj> "#L@IJg]%K$K_'L ## +"&'5326654&#"###!6632@56?*,'[\u4#[_@p  9[15>N"}b7ue><2?\@Y/*0Jc_*K_,K_+L;9-+%# 22 +"'#"&54>32&&#"27&5466323267'>54&#"6O70;z-]`$:)'8T8+"32&&#"7&&5466323267'6654&#"#=6#bi#GpL<#!)9$" &M;>O/  %o" # vhA{b: k+DP$:79 8^7CF*O?fR&B(+<&&[-,,&F[R0Z *@'a]#K$L +7##7!#3-|cFL~~,<u,8m@&7JIKPX@ a_%K$L@  a%K_,K$LY@88(%$$* +7&&5477654#"#654#"#336632366323267/)0"5( /C0"5' 0to U98= W9DD   C 21"#<8_;?#<9`:"e1>;41>UH#4 [<2:""@J%K'L+7336673E3F  3"=<"%/@,Jf#K$L+37#737333#s?~!G~:"/@, Jf%K'L+7#733366733#E~~F  ֆp"=<"p0/@, Jb#K$L+7##3733-JTtKWF uU<D"/@, Jb%K$L+7#'#3733X.N=n8wACħ R0$1@.R]#K^$L +7!#7!#3332-#|a}|fHL~~2L-<"(|K'PX@ 'J@ 'JYK'PX@R]%K`+L@b]%K_+LY@(($$' +7&&'##"&54677#7!#32667733267/R5GF'zy+2#7( 0O  C /,6SC9pp#99`: Z04@1Jha#K$L%#+7##"&&5473326733-:$Y-,Q375K&G#D~FE:   @@P<V"4@1Jha%K$L$'+7#7667##"&5467733267733/ F,CJ:2= ZnCĔ. %UH9v#>ec>XZ7@4J~]#K]$L+!#7"&&5473736673z:,"G 1U475="G!+D E:   : @6PK" bJK PX@p]%K^$L@~]%K^$LY@ +!7667##7"&5467737366773D $CMP#C"- t,!zhUH9v#. pj`M>f+@(Jg#K$L%#+336632#76654#":$Y-,Q375K&G#DE:  @)K +7KPX@ ()J@ ()JYKPX@%h_*K%K_ +LK,PX@*Xh_*K%K_ +L@-~Xh_*K_ +LYY@53.,&$ ++ +"&&5467&&54673336632##3267326654&#"au5MX{ )ff4AK0W()b-9b;"!*L: K}L  >86%eSp LU~1,!-N |,)3K@H&'J~g_,K_+L1/,*$" )) +"&5465&&5473>32##326732654#"l`xBIh NuN[\2/+F0+YmUK35) hkA/1( !Cl@TAVh ,4oF5#."<0 -9KPX@ )*J@ )*JYKPX@* h _*K%K_$LK,PX@/ Xh _*K%K_$L@2  ~ Xh _*K_$LYY@750.--%$# +7.5467&&54673336632##3267326654&#";.=I"MX{ +ff4AK0W(BY*]-9b;"!*L:Nj=  >86%eSp LU~x1,!-N <|,*4H@E%&J~ga_,L20-+**%$# +7&&55&&54733>32##326732654#"-=HDFh NuN[\2/+F0"D)';UK35)cR=/1( !Cl@TAVh ,4o5#."<,&$3+ &$!g@JK2PX@]#K$K_'L@c]#K$LY@ !!+"&'5326654&#"#33 %I ?(6O,HM(5G0W8$Ly  J]%K$K_'L +"&'532654&#"#373;5@Q9:" &t6بEN"Gm  ^\4E" lY?tY40KPX@ J@ JYKPX@]#K_$LKPX@$~]#K_$L@(~]#K$K_+LYY@%'+7###"&'532667667!3}('!CR8$ (&E,}LLy+U]#|77D<u,#K'PX@ J@ JYKPX@_,K_$LK'PX@!_,K$K_+L@(~_,K$K_+LYY@##'#'#+7#&&#"#"'532667>323\jw\(1%!,?/*"0@bJ2ZX|.ZC2XC& y/N.EfB! ]j@ JK2PX@f#K$K_'L@fc#K$LY@ +"&'532677##333 *E =+AN4A;; T^R W"A@>Jf%K$K_'L +"&'532677##3373%=658+0u-,ty  FC"z{06@3~f#K$L +7###3333AA;;|4<v"6@3~f%K$L +7#7##33733]jw/0u-,]|"KZ07@4Jh#K]$L%#+37#"&&547332673#H!$Y-,Q375K&G#D,HE:   @@6P<B"7@4Jh%K]$L$'+37667##"&546773326773#Jw E,CJ:2= t)>2 %UH9v#>ec>06@3 J~#K$L+7#>7####3333MxG  F  |RA@2 ) 5A@<'#6@3 J~%K$L+7#667####3333jt<ύ 5s^&Hn(B #~J,&$$<3+,m &D$Q&$jD3+,A&Dj,O,z&($3+,a &H$!u)C@@Je_*K_+L! %# )!) +"&54>336654&#"56632'267#"nk&Zp4EF5X))b=ax7;Z{NJdKg\) eS2VB% HQ~JO>v\6~aN?1 ,%C@@Jg_,K_+L" %% +"&546336454&#"56632'2667#"\[3.+F0+X;`x'MrB6*UK TAVh ,4ohkEd;j"<(5#.!u&j@3+&j&j3+&jJ&j3+ &j7@@=J~]#K_+L +"&'532654&##77#7!8`&?AKZ6HKS]M   <;(3d}` \POl6 "@@=J~]%K_'L +"&'5326654&##77#7!8[%(\";L%=BBU_L)D)/=ir`gLWGm&L3+6K&XLj&j3+6K&Xj<&2jw3+,&Rj<_,,`<&_j\3+,&`j E&j3+&jm&L3+;&\L-&j)3+;&\j&R}3+d&\R+Z&jI3+PB&j0> (@%a]#K$L +7#!#3w-dF|*<" (@%a]%K$L +7#!#3b/th@nC"yz&j3+4&jj>&x\i"U@RJ  ~ e]%K$K_ 'L  +"&'532677#7#737!#3#3k/ * ,DD0i&]u"1'syjsL`UI@F J~#K$K_'L +"&'532677##3733/ ) LTtKM+^u"1' uU`UD"I@F J~%K$K_'L +"&'532677#'#3733J/ ) K=n8w?&^u"1' `U5@2Jf#K$L +##733733##9pzcKxzoT.| | D"5@2Jf%K$L +#7#73'3733##'1]aY8wada=p֣pܧI 2@/g#K]$L      +!"&5466333'37#" p~MW29$)%9N3eePj46|1<*),nG))H@EJ~g#K `+L %#) )  +"&'#"&5466333326773%2677#"/S"F6\`NX/:l"( )0s+ @S% !dRUw? 27g]}#*|@A%#,3'7N@K $J~_,K `+L)(1/(7)7"  '' +"&54>32346773326773#"&'#'2>54&#"[[=]>1>%u'$ !oZ?P%W /!!#/"% la:~mD." A  3?,!T(#0g=8Y3F60* $% !s MJ+g&k;1;?4(-2g]@0X*E@BJ~ea_*K$L**%%!% +7#76654##7326654&#"'66323~-'kp>0U6...W+59yXB^2rYDK Fв  Ru*(") f%*.K-XXI8 1W<2,*D@A $Jea_,K$L**%$!&+7#76654&##732654&#"'66323g/w..V=>?!*!Q(#0j=8Y3E:)1nCz #g$k;1;< 0(.B@?J~]#K_+L'& ..+"&'532667667!326773#"&5467#($ (&E,i") )0ta[oJ('!CR |77D 27g]RS'\Ly+U]#H,2K'PX@#J@#JYK'PX@ ~_,K_+L@+~_,K_+K_+LY@/.+)! 22+"&5477&&#"#"'532667>32326773fa0u-,G!"' !s [H " 27zg]<">@;  Je_*K_+L ""+"&54>32&&#"32667#7!U5if>g&8 F5=_B!AI2E) PO YJ{6\t=IU*H-~YeM,M, >@;  Je_,K_+L   +"&&546632&&#"3267#7!Cj32&&#"33#"3267Ip@6a>9=/M^.Oj.E V22==PD<4`>C<5e &m *R=@Q, I87M0(n,((-v10-& ,(KPX@J@JYKPX@)~]#K_$K_'L@-~]#K$K_+K_'LY@%$#" (( +"&'532677###"&'53267667!3/ * }":CQ4$  6F0y+]u"1'LDKT"|1CB`U,/KPX@* JKPX@* J@* JYYKPX@"_,K_$K_'LKPX@)~_,K_$K_'L@-~_,K$K_+K_'LYY@,+(& // +"&'532677#&&#"#"'532667>323/ ) \(1%!,?/*"0@bJ2ZT&^u"1'.ZC2XC& y/N.EfB! p`U.8&$ V,.A,&D E8&$H~3+,A>&DHN&$S3+,,&DSJP&$T3+,A-&DTJ&$U3+,g&DUJi&$V3+,As&DVJ.b&$' VJf3+,.A&D' EJ1b&$W3+,AL&DWJb&$X3+,AL&DXJb&$Y3+,An&DYJm&$Z3+,As&DZJ.a&$'Mt V3+,.A&D&M? E.@&( L,.,&H K@&(H\3+,>&HH?T&(QL3+,;&HQ3&(SW3+,,&HS>@&(TW3+,-&HT>&(UW3+,g&HU>A&(VW3+,(s&HV>.@&(' LJ>3+,.!&H' KJ%&,H3+k>&'H.&, .?&L <.&2 ,.,&R Q<&2H3+,>&RH=<0&2S3+,,&RS><&2T3+,-&RT><&2U3+,g&RU><&2V3+,(s&RV><.&2' J3+,.!&R' QJ%<n&Dv3+,&Ev<n&DC3+,&ECQ<n&DH3+,>&EH=<n&DQ3+,&EQ.<.n&D ,.t&E ^E.&8 y6.K"&X BE&8H3+6K>&XHPE&Fv3+41&GvE&FC3+41&GC_E&FH3+41>&GHPE&FQ3+41&GQ<E.&F 4.1s&G X[.&< 6;"&\ 3+[&<HI3+;>&\H[&<QJ3+;&\Qb&Bu^^~, >@; J~]qL    +566735>73#&&'K,y .2]310[*3 ; (( _ 24!N ,$^- +@( JU]qL  # +&&'535>73#&&'V4 q ;310[*3<5` 24!N ,$^^Mg$p@  !JK PX@pg]qL@~g]qLY@$$#& +76654&#"56325>73#&&'A) #(,Kc310[*39  ;':] 24!N ,$^^s+x(#JK#PX@ g hqL@)~ Wg` PY@++%$ $"$" +663232673#"&'&&#"5>73#&&' ;(@6)"n1/4[..;;  ?8  -/!D '^L jJK,PX@~dqL@"W`PY@     +56673"&5332673,j -3NFH$//7Ia : (( XM&-0#J[^L UJK,PX@dqL@W`PY@   # +&&'53"&53326734 g @ODG$//7Ia<6TQ&-0#J[^n@ JK PX@pgcqLK,PX@ ~gcqL@*~|gW_OYY@#$ +7654#"5632"&53326733"(!!MFG$//7Ia61"%xOV&-0#J[^s'?@<g g c qL%$" ''$"$" +663232673#"&'&&#""&5332673 9'?8&MPGH(.31 H^66 :3 JG "APy+@(J`'L +"&'532654&'3$ X$OX0>&=7+@(J_'L +"&'5326773/ ) (+^u"1`UNZ&7z.&Wz'.KPX@  J@  JYKPX@'fqK _rK _ xL@+fqK _rKpK _ xLY@! (& .!.  +"&'###73733#36632'2>54#"*4Aq|FFA/'G,$B]S/#@$2 % ,$FHaOOa<+&SCCk@w+FV+L1KO'/?&/{@ JK PX@&pe]oK]pL@'~e]oK]pLY@/-)'&$!5$! +3#"#&&546332#32654##32654&##}!)oiif|RJ1:JPI5ASJcX7C,-QN,# TjJUI^ E5Qg1+1C/74&)BU+KPX@ J@ JYKPX@"]qK_rK_xL@&]qK_rKpK_xLY@%#++  +"&'##!!36632'2>54&#"*4AqA/'G,$B]S/# $2 % ,$Fp56*&SCCk@w+FV+($1KO'/=J2@/foK_xL  +"&547332'26654&##"i|i:LYm1KK#<%4CO `S3Y8Tq9|5,(*bE="&:@7 JqK_zK_xL && +"&547336632'2>54#" bk g&:4FR*B\;!1 A 2!$ j^),C!0j^,e`N/w2MRX/JS$.*L& ʰ3+<o,K@H )*Jg_wK_xL'% ,, +"&54>3276632&&#"&&#"3267B;Z|P.L9!  %(\-3276632&&#"&&#"32679\6&JlE  O@" )A%/A",(%?"#N (YHIf:)\P r El9//x2!bJK PX@p]oK]pL@~]oK]pLY@!5$! +3#"#&&546332#'326654&##}!)oii܃]-4Rj4I@8N,# Tjm}WROKU9@6g]oK]pL  +!"&&5466337!7!'37#"Wk1SW1+)"@U44\;Qi3}6|84)+,n)KPX@ J@ JYKPX@"]qK_rK_xL@&]qK_rKpK_xLY@%#))  +"&&54>32346677!7!#7#72>54&#"(F,#B\:/< p K "2#"$:" 'WIDe<(%0?pG$-w5OQ#)Bk;V&--~H# #3+# /@,e]oK]pL  +#737#737#7!'!}||6!u|+J@G()Jg_wK_xL&$ ++ +"&54675&&54>32&&#"33#"3267}m>O2Ra.Vs/B#V5D@Lc9@qzMD1j1/n iV[a  F<:N.)$f/*&.v5=.+{>>@;Je]oK_tL  +"&'53267!#3#- "'I-F r||BM!<o/R@O Jge_wK_xL,+*)&$ // +"&54>3276632&&#"&&#"32677#7!D|5jg+O9"  %.T+Ba@ DL% O1m [JPC r$8]p8PS~U#1@. JoK`tL## +"&546736673'2654&'9BA1r2 " NE!C49vGM88 Q#0,X'YdY9%*,P!0eKPX@qK_zK_xL@%qKrK_zKpK_xLY@-,)' 00 +"&546776654&#"#31363232673Bdm#6& 3!<\?PD,0=@w UR(V !;[0>)SPIo DBM%~y2B+@(JoK`xL  +"&546733267@Nop"C 7G "   n 3@0JfoKpL +#?#737'7!3#[$WV$J<]$ZY$LV(|(VV(|(VT@  JKPX@_oKpL@oK_wKpLY@ %& +3377>32&&#"#KN^";@, $g=5gt*=" x!"i7@4J_qKrKpL%# +36632&&#"373#'~VM(  $ݨY;$SUW rB#L '@$fqKpL  +3#7333#ALLHHNNA4pTp)KPX@& 'J@& 'JYKPX@~_qKxL@~_qKpKxLY@#" )) +"&''&&'#''7&#"'63273267:9  x+\^  ,2>MLO2 - CBbE>Nx 31O:)r ;+lKPX(!J(!JYKPX@oK`xL@oKpK`xLY@&$  ++ +"&5473326673326673#5##"&'#G\je #)6" [eF*6! Xo"[35E#] VO#"#.L,#G3T06L++0*+/ :@7 JoKpK_tL    +"&'5326733>73##*" H TN rCHR6->ApbN),<_4&5k@  JKPX@_wK_xL@_wKpK_xLY@('/-'5(5 && +"&54>326632#654&#"'26654&#"=-]bGi +[D4S2ef,( = ,[W:`9=<.O9 B {TQ0*'3+P9 %'*+2WOSfBO5^yEGJ,I,(6@@= J_zK_xKtL*)1/)6*6((#')& +6654&#"#"&&54>32663226654&#"7v& ."GmJ=_5$HmIo7(O2-O0u?)9'!2 / & E~b93^AHc8K(##H9)^Bi;)7-HR%Z2"iJK PX@!pe]oKpL@"~e]oKpLY@" &5$! +3#"#&&546332##32654##}!)oiiWi/RXL5P=CR_FN,# Tj4^>Up7zB:X'%5P@M J_qK_zK_xKtL'&/-&5'5%%&(%# +6632&&#"3632#"&'#2>54&#"!VM( ?KDV=\>2> #/"% /"!CUW r7Sbe54&#"'66323267ln:^6.K,(%#C0*6`><[29dB+B&.+4S6,d iPG]9)"u-Q6FW9)"%~,'7@4$%J_zK_xL"  '' +"&5467>54#"'66323267ceV\45=#J %4\1\a,P665(!&M/+O UHBV$ iMA8E+pAn;!.C@@Jg_qK_tL#"+)".#. !! +"&&5467#"&546323267376654&#"&G,{7ETBGI*F@:2  B:5>CC7{ o J&.%@"JK PX@*n~]rKxK_tL@)~]rKxK_tLY@  %% +"&'532677"&547#?33#3267%# MG8J`@_83*Ih !?7#7!32>54&'7!#AZw:&>G!=Zc>@3J/'%*,?+X CrILsR75kCO/MW)Ob#qSHk>E']@ JKPX@_oK`xL@oK_wK`xLY@ '' +"&5467332676654#"56632'os`_\AA:'<2<<H} n['?%WKJ +u &>%LvDPkKPX@ J@ JYKPX@~wKpL@~wKoKpLY@ $% +3'.#"566323:9 08?+:)* u <<!G`,%d@ JKPX@_rK`tL@rK_zK`tLY@ %% +"&'5326773366776632&#"" .< PKP=('!,uu6*""ME ;D u))cSOJ3@0e]oK]pL +#77#737!7!3#!\a#b|}c|}"3@0e]rK]pL +#77#737#7!3#3tJVndK`Xairbyatr7^M@J J~|]oK`xL  +"&54667'7!!#"3267 K~M5:\6F:0X5/b qVOb.a}j0,-/}4"E@B J~]rK_tL  +"&&54667'7!!#"3267Pss]'4W>h%%xHG%dr` IB(B4$ ' n*=@:Je_qK]pL!%% +#77#736654&#"'66323#!ߤ+*("$D.G2vMbg("Dha(J(#%%c+:gP.VaLA@>Je]oK_xL  +"&'5326654&###7!#326e !g,/R2?Bp:O dpS 91,)~~mZ_v6"H@EJ~|]rK`xL  +"&'532654&##7#7!#325ib.FR@A[,R\j x#(ppaIGaj)f@ JK PX@n]rK_xL@]rK_xLY@)) +"&'53254&'&&54677#?33#1aU*m')\`@_00g v@5/ H)stp#  )4$4Q0',JJKPX@_rKtL@rK_zKtLY@ $ +336632>54&#"!pK6FR7fY/J32&&#"32677#737#7!3#D|5jgk]8$H+Ba@ OE( wy %>?1m [J0{8]p8]P)a0~a A,*:KPX@!  J@!  JYKPX@*   gf _zK_ tL@.   gfrK _zK_ tLY@!,+42+:,:('&%$# ** +"&'53267#737667##"&&54>323733#2>54&#"=P%&U//tM3'C)$B\85=qwGO"} /!$/#%oM%/"*$OB?{f<+%FMSB{+CL"#+'@N'''<&*K3+ O&JK3&.Ky3+i&NKְ3+<&2P,,&RP<m&2'LP3+,&R&LYPH&K,3+&K&'=}&'],*&G]R<&*v3+ A&JviKPX@ foKrK_xL@$foKrKpK_xLY@  +"&5477##33332673epA;;fG/2@??k XSV @?F-Sq9JJKPX@_oKtL@oK_wKtLY@ $ +336632>54&#"yU;5R.jԞ4Q?lQ-/'?G\&A1Y=pˡ.Kcp8+0cM&1C3+)&QCi8&$ `3+,A&D +Y&$ ^3+,A&D )@&( 83+,&H @&( 63+,&H &, 3+N&' &, 3+&' <&2 3+,&R <&2 3+,&R H&5 W3+&U P&5 U3+&U E&8 |3+6K&X 0E&8 z3+6K&X .Lo(#@ J  G_wL +7>54&'5>54&#"'6632-\yD Uf\G5/6k2-BJasK54'5>54&#"'6632GG}b7'H(@g>*!(L&.g59Z4?4%;gw#2F1/!  j$3&l"D4;M"A.CdI2%&+K3+)&KKְ3+SIKPX@_oKpKtL@oK_wKpKtLY@ $$ +654#"#336632W0U?K} *gJ6T0 %WAoDs5I/V:!*E,*0?Jb@_#HJGgqK_zK _xK `xLA@21FD@JAJ:81?2?$('* +'667&&'##"&&54>323467736632#"'%2>54&#"2654#"M ) *R4(F,$B]:18%s VA>=mc"" "2$ /#&0* / H  '43'WIBj@.">!  6=:2HB 5OQ'/+FV+V$!'$&!.`JKPX@goK`xL@gdoLY@#")'".#. !! +"&&547&54773326773'2654&#"C`>G9=JPF@^W]^]GI5W4J;gCF*TMM  )2J@LLEk9ieB[O19"I;2<)#2<@9JhqK_xL%$,*$2%2## +"&54667&&546773326773'26654&#"n0S2!#H3.D?^ET1<3+*7!7 tdHiA@. &cc#JIGdrKa3wWHx5W2-3$9@24Jj@ JK2PX@ ]oK]pK_tL@c]oK]pLY@  +"&'53277!7!7!!%- {#(Ih :@b}cZK"w8&$N3+,A&DN@&(z,,&Hz<&23+,4W&R<&23+,,W&R<&2N3+,&RN<&2m,1W&R[m&<Lp3+;&\L-&=@: $JGhqK_xL" &&%" +'>74673632#"&'72654&#" K )0qq/3F/O2:Q %( !0D:) <40>, &,j ,-8KPX@6+JG@6+JGYKPX@ g_rK_pL@(grK_zKpK_xLY@/.53.8/8$'$+ +'667&677654#"#3366326632#"&'72654&#"\@*5"5' 0tp  S9FG $4CeO)F "%6$&8=~#<9`:"e1>UH$4S67IF)l +|@)JGK PX@%ng]rK_xL@$g]rK_xLY@"!(&!+"+$# +'667&677#?33#6632#"&'72654&#"/@* 3J`@^,%5BdP(H !%6$&8=H)stp67IF)l,P'7FO@L %JqK_zK  _ xL98)(@>8F9F1/(7)7#! '' +"&54>32366773136632#"&''2>54&#"!2>54#"Zg$C^:*<  & :4FR@fG<[V)"2$0! X!1 A!1$ iaDh>+%$H4%!0j^=mC2.,4w0KV&-$3MP+/2MRX4RY%%,*P,|" "3+TE@BJ fqKoK pL +#373#'##7#37&&5#'<v\W; dv^w&T&m E.)(599<"+G@D %!JqK_wK_xL(&""%)) +7&&54>3273&&'3267#"'#"x277;Z|P#\!:(T)dA'"#3273&&'3267#"'(U%,&JlE>\G -  %?"#N3G;+<T@If:pxf Fg -@*foK]pL  +3#7333#3>A@?@qp##|+|}h6@3JU]oKpL +#7!733##708^4i3%^rXZ,p~MM~^[ ,9I@F 67J_zK_xK_tL42-,"  99 +"&&'&&'&&'532654&'&&54632&&#"32672<$  %N)#6 237nb/X*0A & *1Asa   )$C/'-y @4UYiD8Y_ %"r"=@:J]rKpK_tL  +"&'.##7#7!327GI " #n'"JN(XXrb 3,5/ qJ)@&  J_wKpL%' +3>54&#"'6632JE2a@.#,M04fCE[,wl6F6N7"(# k"0Q2i/!,)@&  J_zKpL%' +37>54&#"'6632?!2b@.#,M04dCE[-wo5N7"("k"0R1i.Vc)I@F Je e]oK] pL)('&%#! +37#7332#32654##32654&##3#$KL^f|RJ1:JOI5ASJcX7C,-Q noaJUI^ E5Qg1+1C/74&),a "A@> foK _ xL""  +"&54677#733333#'2677##lrRR7777RRKJ322733267#"&'322776654'7##d+0'MrK UL[..xp2+F0+Y:YZ  ;.@$"[BEd;F/Lc qo  K' % > c.i:@7JfcoL  +"&'532677#7333#B*'0= 6VV>?WV;{|;@|'|{j@ "P@MJf _qKrK_ tL  " "  +"&54632"'53267#73733# */*,+3"- 9LK//KK= -Of!*,!'0 v (+ aa2R1<):KPX@ &'J@ &'JYKPX@"_wK_xK_tL@&oK_wK_xK_tLY@+*42*:+:$" )) +"&54677667##"&&54>3237332672677654&#"HJO &XG=]52^QAG"( 6J^ 7;6Q6@CA  "!1"+5>uS\N6+V'r e{m#;fx9GE,A,'7KPX@$%J@$%JYKPX@"_zK_xK`tL@&rK_zK_xK`tLY@)(1/(7)7#! '' +"&5477>1##"&&54>323733272>54&#"GM D3$C,$B]:1>q~(2#1$ /#$D<!/!"1'WHCk@*&F# q]5OQ'/+FV+++H7@4 Je]oKpL! +3#7332##32654##:LLCk}ZCe::T&@G`${=\hUk89P,KPX@JH@JYKPX@f_rKpL@ frK_zKpLY@%$ +37#737336632&&#"3#/KL0p !T5  'G^h/ae4;.4a.4@1JfoK pL +3'#73'33733#7#:A_154#"*4Aq~VM( >2'G,$B]S/#@$2 % ,$FSUW r7!2'WHCk@w+FV+V4OR'/,7@4J_zK_xL  +"&'7326654&#"566321M"-3 .B",(%?""O38]6&Jl p El9//x(YHIf:,)4G@D3'JGg_zK_xL+*1/*4+4&(%+ +'667&&54>32&&#"6632#"'72654&#"1##"&&54>3234667733272>54&#"GM D1'C)$B]:18%(2#1$ /#$D<!/!#0*XEBj@."%0# q]5OQ'/+FV+++,%4KPX@ "J@ "JYKPX@"_qK_zK_xL@&_qK_zKpK_xLY@'&/-&4'4!  %% +"&&54>323066776632&&#"#7#72>54&#"(F,$B]:18VN(  }p K "2$ /# 'WIBj@."$2NZ rG$-w5OQ'/+FV+V,'C@@Jg_zK_xL'&"   +"&'53267#"&5466326454&#"3=R$(G-AJvw;d>F].%KpL'' #9; o;9_E;M':c?B|b:F 3>" &, ,,:,)?@< Jg_zK_xL$")) +"&546632'2654&##73254&#"lKe^qB<.2Du@*;7(m%:I"9 nnhWPC<= 5-=O&p#$g?Em<:06"=@:JfrK_tL  +"'53267#73733#,3"- 9LK//KK= -O v (+ aa2R1 4D_@\)*J_qK_zK _xK_tL65><5D6D.,'%44 +"&'53277661##"&&54>323066776632&&#"2>54&#"=P%&U/h D3'C)$BZ666WN( !Kk/"$/#%a 0"1*WECk@*&"2NZ rVc*]-JT''/+FV+++ A,J,),>@;  Je_zK_xL  +"&54>32&&#"32677#73 v~"M}[0a%.L'AJm f:+\ zq@w]7p <]2}\c?"$1@. JrK`tL$$  +"&546673366773'26654';>!3e+ QE "C4)RN#9 :<(R$R^Y+%,.M (J,/;C@@"6*# J_zK_xL100;1;'%! // +"&5467'&&#"56632366776632&&#"'2654&'=;53  %+5 ,=)"&d ME  C/8S%`!n(%0$!1#( o#p=KQY%$0 6K"'@$rK`xKtL$) +7>1##"&546733266773$  J0GD>C5!6( 020 %.UH9'#<9`:)';@8J_qK_zKpL''$)%# +36632&&#"36632#654#"~VM(    F1FG AC5"5' 0SUW r$.%.UH$4?#<9`:)2S@P%J_qK_zKpK_tL*( 22 +"'53267654#"#6632&&#"36632 3"- K5"5' 0~VM(    F1FG M .P v (+d#<9`:SUW r$.%.UH$44S0? ?@<f_qKrK pL      +"&546327#73733#+/*,+1KK./LK1f!*,!'0aa/?"" "@ JrKpL  +#77'7!(\CJ8[DJH*>*HH**H7@4JghqKpL"#"" +3&#"#663233273#"'JJ JP2 BL !JO1 ?[RD:5RE>@; Jg hqKpL$! +3#"&5463233#376654#"_>@9G6 9S__>]"$;):=  yMq#F+@(JqK_tL  +"&54673327GL(4@> (## q N@KJ~qK]rKpK_tL    +"&'5326654&##77##3!;7\%(\";L%=BB[.V^L)D)/=iP`gLWG4x"*lKPX' J' JYKPX@rK`xL@rKpK`xLY@%# ** +"&547332667733266773#7##"&'#DD AC0"5' /C0"5' 0to U98= W UH$47#<8_;#<9`:e1>;41>4x"/3@0 JrK`xKtL//$$%) +7>1##"&'##"&547332667733266773=$  K.-KW9DD AC0"5' /C0"5' 020 ',3<1>UH$47#<8_;#<9`:V,5z@(!JKPX@_rKpK_ tL@#rK_zKpK_ tLY@-+&$  55 +"'53267654#"#654#"#3366323663283"- K0"5( /C0"5' 0tp  S98> V9DD M .O v (+d#<8_;?#<9`:"e1>;41>UH$44S0),$m@ JKPX@_rKpK_tL@ rK_zKpK_tLY@ $$ +"&'53267336632#654#")"p  S9FG AC5"5' =\r_e1>UH$4?#<9`:aR),'m@$%JKPX@_rKpK_tL@ rK_zKpK_tLY@#! '' +"&5467654#"#336632327GLL5"5' 0tp  S9FG K(4@> &h#<9`:"e1>UH$4# q"$@! JrKpL +330>773#0t.t ."&97~"46,,`,9,&KPX@ JKPX@ J@ JYYKPX@#e _zK _ xLKPX@-e _zK ]rK _ xL@8e _zK ]rK ]pK _ xLYY@!&&  +"&54>327!#3#3!7'26654&#"_p$HkHA,{')9'!2 p`Hc8&p`ppr xAh;)7-HR%X",/C@@J~_zK`xL+)#!// +"&546632#"&'#'2677332>54&#"RYd`IApF==M#+( ) Y^Zt7 fWo`F|Q^C70/8t@:``# 3:E^HtCK,"iKPX@ J@JYKPX@rK_xL@rKpK_xLY@  +"&'7326773#7#  7W4tp !T WVe4;iKPX@ J@JYKPX@qK_xL@qKpK_xLY@  +"&'732673#7#  7Wbp !T WVe4;"$A@>!"JrK_xK`tL  $$ +"&5477>1##"&'7326773327FN K.  7W4~(1D<!/!',WV# q,iKPX@ J H@  JYKPX@_rKtL@rK_zKtLY@ %$ +336632&&#"!p !T5  7Wge4;WV,"KPX@  JH@  JYKPX@_rK`tL@rK_zK`tLY@ "" +"&5467336632&&#"327FM{p !T5  7W<(3@> *Ce4;WV# q .)@&J_zKpL%# +36632&&#" La\!6 EJgfa wQ#;.)@&  J_zKtL%% +654&#"56632#~4#ES~O w NH" 3@0Je]rKpL ! +332#'#326654&##tVgP>iV3+@:1 &%;"LGMP/# ~"3@0JfrK]pL  +33373#'32654##t,D&-EqBSP&AMM"=0DU&i(';,7I@F56J_zK_xK_tL31+( 77 +"&5467732654&'&&54632&&#"#"&'3267Y=D.%N)#6 237nb/X*0A & *1A}i%  ">9   @4UYiD8^`A h 7@4J_qK_tL  +"&'532676632&&#")"UN(  \rOZ ruaR#L@IJe_qK_tL  ## +"&'53267#7376632&&#"3#)"?KJ6UN(  4LL>\r(pOZ rpaR .#:@7 !J~zK`tL ## +"&5467654&#"56632327GLR  - >JT(4@> ( w LC!u # qQ&I@FJg_qK _tL" &&  +"&546336632&&#"3#'267#"/=C[QUN(  }IJ.KE#>,@FVOZ rM0I*R&+ l,W" "3+ f@ JK PX@n]rK_tL@]rK_tLY@  +"&547#?33#3267AMiJ`@_i$B7GH)stp  n f""KPX J JYKPX@  frK _ xL@#  frKpK _ xLY@   +"&5467#73733733##7#'3267#GDED****EE5p  R25'= UH8aae1>N=3)D){#N 6]%  Gp@"Y" "3+"Z" "3+L\" "3+2T""@JrKpL +37373+F+V"@@=J]rK]pK_tL  +"&54677!7#7!33267^=Dn'  ">9  KXXrb h "$1@.Gg]rK_pL$#$# +'667#7#7!3>32##7326654#"Cn2'?A*26wjD v+!*W" XXrb3G%?1SN)% " "'2@+ %!J"GKPX@)~]rK_xK_tL@'~g]rK_tLY@)(/-(2)2'' +"&5466326654&##77#7!&&''267&&#"vVl.L.@X" HB85Q.Q  O"SJ>:$<&JI2B!6%#3@ir`5S3K 6 m &3P )@&  J_qKpL%' +3>54&#"'6632PNV]%,&,Q14n;C\1{m@oFF"-" j"2T4_%W$+@(  J_qKpL%' +3&&546632&&#"A@AExN@Y)DD)/EANN0(jGPm7#j!?7.U-@* JqK`xL +"&'732654&'3@^)CE(/EANNAA@Cv "j A7.Uq)jFOn9 ,7@4  J_zK_tL  +"&&54>32&&#"32678^8)UX1M"-3 2L22(%7"#P.nag›[p MIH:x<&2 3+"!9@6Je]rK]pL!! +332#32654##32654&##rM_9=%,9a; K(1?KJV)2 !R"8A6H6(>P%J"%4*)"+,+?@<Jg_zK_xL'%$"++  +"&546675&&54632'2>54&#"33#"eu$>'(,{os@d0=! ;0#.-)?5+ RF-7 5)NWz}[Tn$=K&I= g""!,.P@MJe_qK_zK_xL+*)(%# .. +"&54663276632&&#"&&#"32677#73q|Do,IA" .G'-P245f:.` whcYQ@E rJo *_M5=\cW"R@ &K@Hh _qKrK _ tL " &&    +"&54632"&5463333#'267#" */*,+>B[QuuJJ /MD#f!*,!'0>,@F"M/J*R&+ '")@& JrKpKtL +667##73773NݨY;$mB,#"@rK^pL +333t\"Pr,*:L@I"#J_qK_zK_xKtL,+42+:,:**%*') +7>1##"&&54>323066776632&&#"2>54&#"$  D3$C,$B\917WN( !#1$ /#$20 "1'WHCk@,$"2NZ r]5OQ'/+FV+++ 7@4Je_qKpL%' +37#737>54&#"'66323#PWVV]%,&,Q14n;C\1{mihaFF"-" j"2T4_%CaL$9@6Je_qKpL%' +37#737&&546632&&#"3#ih@AExN@Y)DD)/EANVVaC(jGPm7#j!?7.Ua,-0KPX@ JK.PX@ J@ JYYKPX@ qK_zK _ xLK.PX@5qK_zK]rK ]pK _ xL@0qK_zK]rK]pK _ xLYY@ 0/(&- -  +"&&54>323466773!3!7#72>54&#"#(F,$B]:18%.u K "2$ /#! 'WIBj@."%0brG$-w5OQ'/+FV+VK,6E;KPX@%0 JK.PX@%0 J@% 0 JYYKPX@1  ~qK _zK  _pK_ tLK.PX@?  ~qK _zK ]rKpK  _xK_ tL@=  ~qK _zK]rKpK  _xK_ tLYY@!87@>7E8E.-,+#! 66 +"&'5326654&##77##7##"&&54>323466773!2>54&#"c7\%(\";L%=BB[p K4(F,$B]:18%.V^LD"2$ /#)D)/=iPG$-'WIBj@."%0`gLWG_5OQ'/+FV+V,/>AKKPX@ JGK.PX@ JG@ JGYYKPX@)  gqK  _zK _pLK.PX@?  gqK  _zK  ]rK _pK _xL@9  gqK _zK ]rK _pK _xLYY@10JHDBA@970>1>$#'$ +'667!7##"&&54>323466773!3>32##%2>54&#"#326654#"C K4(F,$B]:18%.w2&@A*17wjDW"2$ /#!+!*W" G$-'WIBj@."%0b3G%?1SN)5OQ'/+FV+V M%.#7KPX@ J@ JYK PX@ n_rK ]pLKPX@_rK ]pLKPX@)_rK_rK ]pL@'_zK]rK ]pLYYY@&$21$7&7 #" +3"&547#?336632&&#"#'32654&'&&5467#@N8J`@_$/X*0A & *1A}i#6 237q87@H)stiD8^Vp @4  .,7@"# JK PX@3p_qK ]rK _xK_ tL@4~_qK ]rK _xK_ tLY@.-21-7.7'%  ,, +"&'532677#"&547#?3376632&&#"267#*"A&@N8J`@_ VN(  \^6A8rK 7GH)st2OZ rwaR] 4 .@>IKPX@"#H ;J@"#H ; JYK PX@*n  g_rK _ xLKPX@)  g_rK _ xL@;  ~  g_zK]rK  _ xLYY@#@?FD?I@I971/'%  >> +"&547#?33#3267&54>32&&#"6632#"&'%2654&#"@N8J`@_8E)&JlE1M"-3 &<(H.@E&?J$4d&RI9%@ 7GH)stp If:p 1R0 F5/B)/"m#,RDKPX@. -J@. -JYKPX@*_qK _rK pK_ tL@5_qK _zK ]rK pK_ tLY@@?>=971/,*"  DD +"'53267#?6632&&#"336632#"'53267654#"##3"- dPY cP"9'"  T9GF M .O>3"- K5!6( 0\i -O v (+G))cO m ' e1>UH$44S0 v (+d#<9`:2R1)KPX@J@JYKPX@qK_zK_xL@ qK_zKpK_xLY@ )) +"&'#332654&'&&54632&&#"Lo10e6"7 237oa/X*0A & *2@} # @4UYiD8^` ,@)qK]rK]pL  +33!3%#.wbrcM ] I@F J ]oK] pL    +37373#'37373#'wT je m\hkT je m\hkzPP]?@<~e]oK pL  +7!#7#7!#7#s66u55u3 P./}KPX@ J@ JYKPX@~zK`xKtL@#~zKrK`xKtLY@//)%*) +7>1##"&54677654&#"566323266773$  J0FE  - >J5"5' 020 %.UH3jw LC!{#<9`: P.;KPX@ 9:J@ 9:JYKPX@$~zK`xK_tL@(~zKrK`xK`tLY@8610,*! ;; +"&5477667##"&54677654&#"566323266773327FP H0FE  - >J5"5' 0'%D<#5)*UH3jw LC!{#<9`: # qAGK5)&f 3+AG05)&f 3+GM5)&f 3+A_mGU5)&f 3+<gGC5)&f 3+<gGE5)&f 3+AgGK5)&f 3+]VgGZ5)&f 3+gG\5)&f 3+4"48&maM1+dD@ HW_O +D72654&'7a/3(BMCD9)/7{H/ $dD@ GW_O +D&&5463"+7S@H71>9Fgr6dD@+  JW_O%& +D76654&#"'6632y7<)?&FBDH f +  LE0:G2]8dD@-  JW_O%% +D7&54632&&#" W]P';%%%,(3"S@P M ! fl^Q 3+l^!Q 3+RY'dD@Jt +D73#'Ry#k;DNov/ /3+mT&dD@U]M +D73m%d%Tq^v^aC2KU ް3+M LY 3+4CT ְ3+4vT ְ3+ ,dD@!JU]M +D'37:v;苋o dDt +D'3:u u3+1u u3+~  3+)~  3+  3+M dD@U]M +D3#+ M<p;V 0+'7'77'!H.3/H"I/4.;*<;+<<+;<*;FgG-5)&f 3+A GO5)&f 3+<[mGV5)&f 3+gG[5)&f 3+nG_5)&f 3+NT,dD@!U]M +D!#5!nBPNT0dD@%Ue]M +D!#5353BBPNT0dD@%Ue]M +D!#533BFB(PNT0dD@%Ue]M +D!5#533BBPLR,dD@!U^N +D3533LBBnPNT,dD@!U^N +D733NBĦjBNT0dD@%Ue]M +D733#NBĦjB9qKU ۰3+nS)5 53+47'dD@Jt +D'373J`K:vRކ'dD@Jt +D73#'E0`K9w܄0+'7% k1kH@=0+77'7E H@=Bk1LC 3+L  3+,R 3+7\QT ڰ3+8>,Ұ3+%NdDK PX@oU]M@U]MY@  +D53#q5q%NdDK PX@oU]M@U]MY@  +D5#53qq5DNdDK PX@nU^N@U^NY@  +D7533D5qq5,NdDK PX@nU^N@U^NY@  +D75353,q55q0QdDK PX@nU^N@U^NY@  +D53!538M9Хcc0NdDK PX@nU^N@U^NY@  +D53!8ХcBK 1dD@&JH GU]M +D'57!!O1;DHf*- * 3+$ =JKPX@ ]:L@U]MY@ +56673H32#"&'66322654&#"26654&#" jpfaKJ6X1&@! Y3U`H/#)=.`#;"/"*B1 r=!dD16@R+4fVUGY# 'E-(1'"8;$R'=S 3+Z&=j3+,"6@3'J IK2PX@$~_8K6K_:L@&~|_8K_:LY@20)(!66+"&'53277&&5467#>54&#"'66323327&. (/5- /)D( ;6"'Hh :J:8)O"$`gc'! f@7/D ^mk.  ZKT\JK2PX@g_=K6L@g_=LY@(+37&&54>32'2654&#"]d(Va`FMcZiJMHV&I^Dz`7ExN[Xga?Q8\6BL,,2@/J_@K]:L(+7&&54>3226654&#"r48B$HmI_p1fO2)9'!2 cIHc8rfSd^Bi;)7-HR%ZPS@  JK2PX@_=K]6L@a_=LY@ %%(+37&&54>32&&#"33Wp5`N>a,: I)>\2XW.6sdL^3z9b;?C,2,(4@1Jc_@L((+"&'532654&'&&54>32&&#"98-2&BK#IpL8M04#.C$'0 K PX@ pe]5K6LK2PX@!~e]5K6L@ ~e]5LYY@ +3!#3#7#'3}m;|u" ]K PX@ pe]8K:L@!~e]8K:LY@ +!#3#7#!%0xlSpsy!(F@C%&Je_=K_6L#!((+"&54677!76654&#"'632!3267Y=K4n.7CC% |  0 724f# e>12 I h++@@=( )J~?K`:L&$+++"&5467756654&#"'6632%3267BF  8?Ap& ) 9G66?^ !  f >0&E=R*'iQ+P@ JK2PX@_=K6L@_=LY@ +!667'76454&''7&#"'6632.O <+H+&a@O@HQUNi & wOmsqc @  H:L+>7'7&&''7&'5[+N4 8}o`aM@KLNT?NPLa1Єn"/KPX@,-J@,-JYKPX@_8K`6LK2PX@_8K6K`6L@~_8K`6LYY@*(!  //+"&&5467#>54&#"'663233267,G*5- -)D( ;6" * >5)J"$`gc'! f@71B ^mk. i:,(7<@95J_@K_6K:L*)1/)7*7((%/+6654&'&&5467>32#"&'#2>54#"2KS Y|Pdq7###_ŗD v]  FU6E*dUMP^,"X JK2PX@~8K6K:L@~]8K:LY@ +373#667#'"KsG hUzM,,',(J@G'J e_@K _6K:L$"((%$ +73>32#"&'3##72>54&#"XDO;iXdg=rQ*@  &!0  +4avRyAu_b_""C$a99$3LP+0MO+Le<&&F 3+L&ew 3+P%J"%4*)"(,7@4  J_zK_xL  +"&54>32&&#"3267ac"FnK3H#,7".B+27?Juc<{f?[/JW)?> _ " '@$]rK]pL ! +332#'326654&##rmvDo!'MW$A:*"lmcR^Bj:D=" 7@4e]rK]pL ! +37#73732#'326654&##3#0II.mvDo!'MW$A:*zz]lmcR^Bj:D=]" /@,e]rK]pL  +3!#3#3r+"]z]^-*P@MJ~g_zK_xL$# ** +"'732654&##7326654&#"56632zWI=!3:0)B>$B+5/2U()WAkz-I+$3 =Xg !yUC+>$ 7*HX*")@&crKpL  +33"&54632ttp,+- */"!'0!*,W"+@(JrK_xL  +"&'532673F  $. MpQ\ ],0p\P" %@" JrKpL  +336773#'to8i|K.*"($Z" *@' JrK^pL  +37'7373&&Q7o)4'r K+J>^"'@$ JrKpL +3333#667###t˜tf7 g 6"e&Z!W_/"&@#~rKpL +3333#7>7#u. t5"62gC7* *-@*_zK_xL  +"&54>32'26654&#"af"EkIac!DjA+H+.-.I)1r_@}g=o]Cg=`@uO3=GwF88*7@4J_zK_xL +"&'732>54&#"566322H#+6"-B*27>J1ad"Fl[.KW(>> _ tc-c R75@ 53+. dF8 @  3+ v:3@ 33+D.p$ $3+ 7" ,<@9JgrK`xL"!'%!,",   +"&547&546773326773'254&#"mi5 n +.8< p 31Go57'B'8aK4 >  ?? %80=>4O+Nrg`v$+3*%-0 ,!@_zL$# +>32#654&#"0 FxV_p'#3  QLrf$#$)71M), $@!`xL  +"&&5467332673=_5I0? Dw 3^A#$!Z\CMK" +@(g]rKpL %! +332##32654##rbR>iC)(<2>G%"XFAU*!2.D" 8@5Je]rKpL & +#7&&54633#7#37#"#"&llqp,+'1`.8.Mb0U"%" ;@8JgrK^pL    +3"&5467'3373'37#"P^D2_yL,,nqw 05GOAR],->4"!@]rKpL +3#7!#j__^^<:f"$@!rK`xL  +"&&5467332673M]+>?Q/7?>>p 3T4$(S?G.MuA GX=@ ԰3+ @ ϰ3+{P@ Ѱ3+4" !@JrKpL  +3336673h4l t"/8M>"%'@$ JrKpL%% +333>733>73#&67#Oicyq  v" .31* 6*25, .>6" %@"]rK]pL  +#7#7!33jOodPc"@@=J~]rK_xL  +"'5326654&##77#7!U;O&A'.C8M `) (K^H [^ *&7@4#$J_zK_xL! && +"&54667>54#"'66323267VT-I+#>&A3$ )I.JU-Q51CH'?)"K Q>7G, "-YL=5C,(%7`**6@3'  JzK`xL$"** +"&'73267&&5466323267#"&&'*  4)$5_?/H(,F(&*!2*(:5 Z'*)].8_9&A'4YK",!Z -*(."@]rKpL +3!#t3_"];" !@JrKpL  +#3#&5=}2l ":.N?&"!@]rKpL +3!##tsp``"<"C"+@(hrKpL +37"&5467733326773##XZ&l(+-?h?:9 )m,uq!MC $&&0;dW*"pKPX@ J@ JYKPX@]rK_xL@]rKpK_xLY@ +"&'532667667!##  6!Yto` 1>]))4:qa @EG$5)&f 3+G5)&f 3+FG%5)&f 3+<$fKPX@" e]K] L@ g e] LY@$#! +7#737323##32654##32654'#F+56'CP240S3 /#*60@9#,.@H,3.H1>(!*FG'5)&f 3+FG(5)&f 3+3Gm5)&f 3+\G*5)&f 3+FG+5)&f 3+"RG,5)&f 3+G-5)&f 3+FG.5)&f 3+FZG/5)&f 3+FtG05)&f 3+F#G15)&f 3+F#=JKPX@KL@]LY@ +33#7667'FbX/mbV.5*BTB\G25)&f 3+N G5)&f 3+FG35)&f 3+FG55)&f 3+jG75)&f 3+bG85)&f 3+pG:5)&f 3+RmGD5)&f 3+TmG5)&f 3+RmG5)&f 3+AKmG5)&f 3+AGE5)&f 3+RGG5)&f 3+RmGH5)&f 3+EmG&5)&f 3+AmG'5)&f 3+0mG5)&f 3+=mGJ5)&f 3+(gG5)&f 3+AGN5)&f 3+A`mGP5)&f 3+AmG 5)&f 3+RmGR5)&f 3+.RmG!5)&f 3+TmG5)&f 3+RG5)&f 3+ mGS5)&f 3+SLGW5)&f 3+XgGX5)&f 3+G%eG5)&f 3+WvgG95)&f 3+VgGY5)&f 3+VkG5)&f 3+ G|5)&f 3+HgG}5)&f 3+GG~5)&f 3+R mG5)&f 3+mG5)&f 3+hFL̠)&f 3+FU̠)&f 3+JFX̠)&f 3+>FY̠)&f 3+SkF|̠)&f 3+>F}̠)&f 3+2F̠)&f 3+F̠)&f 3+y\F̠)&f 3+:j,0:KPX@ (.)J@ (.)JYKPX@"h ]rK` xLKPX@&hrK _zK` xL@1hrK _zK` xK_ xLYY@8631-+&$ 00 +"&&54673326736632##3267#"'32654#" K[*>?(%,5?;"SZ2/+F0+Y:q.SUK35) 3T4$(+(CC.TAVh ,4oI )F5#."<'/>KPX@#  J@#  JYKPX@1 hqK_wK _ rK  _ xL@5 hqK_wK _ rKpK  _ xLY@#10860>1>(& // +"&'##&#"#6632733273#"'36632'2>54#"*4Aq JQ1  !JO1 <2(H-$B]S/#C#1% ,$FsRD"O5RE=,$SECk@w+FV+L2LN'/,1?KPX@   . J@   . JYKPX@1hqK_wK _rK  _ xL@5hqK_wK _rK pK  _ xLY@#32;92?3?-,*(&%$" 11 +"&&54>32346677&#"#6632733273#"'#7#72>54&#"(F,$B]:18 JQ1  !JO1 {p K "2$ $;" 'WIDe<."(5*RD"O5REG$-w3MO&-Bj=43=G>G3<4<22%$ +37#6677336632366326673#7&&'#7&&'"654!"76545"Q\N'p  S98> V9DD QZL"#"O)(.)N"00 F%&<(L! $Kc e1>;41>UH$4$!J_  ,% UH$4( =O_  ;/  #<`',0?@  $/JKPX@/g h _rK  _xK  t L@3g hrK _zK  _xK  t LY@21971?2?00")'$"" +7&#"#6632336632#"&'#3273#"'2>54#"! JP2 ~pL5'G,$B]:26  !JO1 /#@$2 %_RDPS#:'WIBj@."(B&5RD2]+FV+V4NR'/,)KPX@JH@JYKPX@$g h_rK  p L@(g hrK_zK  p LY@))2#%$"" +37&#"#66327336632&&#"3273#"&'+ JQ1 4p !T5  5V !JO1 !RDe4;QQ5RD.'I@FJgg_zK pL''2$%$"" +37&#"#663276632&&#"3273#"&' + JQ1 a\!6 E !JO1 !RD9fa wQ^5RD,8_@\ !J~|||_zK_xL0/.-%#88 +"&'532654&'&&#"#667&&54632&&#"2735M"%N)#6 2  J 1!nb/X*0A & *% &J0} y  :D  UYi 57B ^`2@&/ 0 JK PX@/n g  g]rK _ xL@. g  g]rK _ xLY@-+%#!  22 +"&5477&#"#66327#?33#3273#"'3267@N JP2 J`@_ !JO1 %C 7GIRD\H)stp5RD  n "%K PX@ "J@ "JYK PX@(gg]rK ]  p L@6~~gg]rK ]  p LY@%%#2"$ +#77&"#"#66327#7!32673#"&'3"JS9 Ln J2>$! FXRD ]rb%=AUrE&6KPX@J@JYKPX@ g_zK_xL@$g_zKpK_xLY@('0.'6(6 && +"&'##>32&&#"136632'2>54&#",5=qwKkC=P%&U/3@ D3'C)$B\U/#% /!$ +%F/Vc*/2%"1*WECk@w+FV+++/JT%'/AgG5)&f 3+."&@@= Jg]rK_tL!&&  +"&&54667'77#7!'26654&#"Dg9>tQH 11@!EkC):*'0;)/Y=MwD71ird((hI3dQ1m0K+),/K,&/=KPX@7643J@7643JYK PX@(p   qK_rK pLKPX@)~   qK_rK pL@8~  qK_zK]rK pK x LYY@==:921$" +7&&547#?33#373632#654#"#767#"#U8J`@_8LsGF AC5!6( 04wC(?KX2&H)stp iUH$4?#<9`:|n A"3@0JfrKpL +#?#737'7!3#(\LLJ8[JJJH*tai*HH*iat*HH"=@:JfrK_xL  +"&54677#73733#3267AMKJ/.^^ *$B 7G "%aa. # n X, (1@  JKPX@*   f _rK _xKtL@.   frK _zK _xKtLY@ *)"!-,)1*1%$!("( #$ +'7373366323##"&'##%"3654267#J/pL5'G,2-B_:26 #d(6#9%aS#:'WIaAmB."(B&B, VF3'/"!A@> frK _ xL!!  +"&&5467#73733733#'2677#M]+IH....KJ@mE)6 3T4 aaDd6x-7S"$-C@@J  e]rK _xL,+)'$$# +'73667#7!3&&'73#3##"&&5473267!<<w %:{) G- RSNo<=33Oa'5pn8#!8np9%aLj76]< 39>;''6KPX@ J@ JYKPX@'qK_zK _xK_tLK2PX@+qK_zKpK _xK_tL@(cqK_zKpK _xLYY@)(0.(6)6 '' +"&'53277#"&'##3366322>54#"%.  4Aq>2'G,,( IF/#@$2 %h :8,$F56!2'WHJ5ZKS+FV+V4OR'/,n'6KPX@ J@ JYKPX@(qK_zK _pK_ tLK2PX@,qK_zKpK _xK_ tL@) cqK_zKpK _xLYY@)(1/(6)6$#"! '' +"&'53277#7##"&&54>32346677332>54&#"X&. ) K4(F,$B]:18%5%H"2$ /#h :@G$-'WIBj@."%0uZKS5OQ'/+FV+V2KPX@( 'J@( 'JYKPX@-_qK]rK ] pK _ tLK2PX@5  e_qK]rK _tK _ tL@0  eW_qK]rK _ tLYY@.-+)%#  22 +"'53267#?6632&&#"3#3#"&'53277#3"- dPY cP"9'"kkB(H@&. ~ -O v (+G))cO m ' pɼZKh :UP2R1 ,6F:KPX@ ,+J@ ,+JYKPX@1 _zK ^pK `xK_ tLKPX@. _zK^pK  _xK_ tLK2PX@:frK _zK  _xK_tK_ tL@5fWrK _zK  _xK_ tLYYY@!87@>7F8F21/-)'$#"!66 +"&'532677>1##"&&54>323733#"&'53277#2>54&#"=P%&U/3@ D3'C)$B\85=qZ(I@%. ~Kk/!$/#%/2%"1*WECk@+%FYZKh :U"Vc*]/JT%'/+FV+++iz@ JK2PX@$~qKrKpK`tL@!~dqKrKpLY@  +"&'53277#'#33733K%. Y;$HݨX>%Ih :@#BZKFd@ JK2PX@~qKpK_tL@~cqKpLY@  +"&'53277#330&. L5%Hh :@uZKV,8@*#JKPX@(  ~_ rKpK_ tLK2PX@,  ~rK_ zKpK_ tL@)  ~ crK_ zKpLYY@54/-(&"!  88 +"&'53277#654#"#654#"#336632366323%. LC0"5( /C0"5' 0tp  S98> V9DD *5%Ih :@?#<8_;?#<9`:"e1>;41>UH$4ʮZK),&@JKPX@%~_rKpK_tLK2PX@)~rK_zKpK_tL@&~crK_zKpLYY@#" && +"&'53277#654#"#3366323h&. LC5"5' 0tp  S9FG *5%Hh :@?#<9`:"e1>UH$4ʮZK',&5@!JKPX@#_rK _xK_tLK2PX@+rK_zK _xK_tKtL@)grK_zK _xKtLYY@('/-'5(5&&$$)$ +336632#"&'53277#"&'#2>54#"!pL5'G,,( I@%.  26 #/#@$2 %S#:'WII6ZKh :8."(B&]+FV+V4NR'/, KPX@ JH@ JYKPX@$~_rKpK_tLK2PX@(~rK_zKpK_tL@%~crK_zKpLYY@    +"&'53277#336632&&#"30&. Ltp !T5  7W5%Hh :@"e4;WVZK ,5x@"# JK2PX@ _zK_xK_tL@c_zK_xLY@'%  55 +"&'53277#"&'532654&'&&54632&&#"%.  5M"%N)#6 237nb/X*0A & *1AIh :8y @4UYiD8,DmZK+KPX@"!J@"!JYKPX@"_qK]pK_tLK2PX@*e_qK_tK_tL@%eW_qK_tLYY@('%# ++ +"&'532676632&&#"3#"&'53277#)"UN(  c(I@%. ~\rOZ r-ZKh :URaR2:"l@JK2PX@~rKpK_tL@~crKpLY@  +"&'53277#3366733&. C  i%Hh :@"CA"KZKD"s@ JK2PX@ ~rKpK_tL@~crKpLY@  +"&'53277#'#3733'%. =n8wGA%Ih :@ ZK"j@ JK2PX@ ]rK]pK_tL@c]rK]pLY@  +"&'53277!7#7!3%. n&Ih :@XXrbZK,H,)9KPX@ '(J@ '(JYKPX@$_zK _pK` tLK2PX@,rK_zKpK _xK` tL@) drK_zKpK _xLYY@+*42*9+9%# )) +"&&54677#7##"&&54>32373332672667654&#"!;%(K4(F,$B]:4Aq]6%'  $4%$ /#4)  EG$-'WHCk@,$FK "h S0K+$.#-+FV+V,H,x,6F_@\&'34J_qK_zK _xK_tL87@>7F8F20+)$" 66 +"&5477>1##"&&54>323066776632&&#"3272>54&#"GM D3$C,$B\917RO' 3 (2#1$ /#$D<!/!"1'WHCk@,$"2"@U r:# q]5OQ'/+FV+++,,-7@#+,JK2PX@(g_zK_xK_tL@%gc_zK_xLY@530.)'! -- +"&&54677#"&54>32##3267326732654#"!;%  `x'MrK[\2/+F0,'  $UK35)4)  =hkEd;TAVh ,4 "h "5#."< ,:@089JK2PX@(e_zK_xK_tL@%ec_zK_xLY@64.,)'&$! :: +"&&54677#"&54675&&546632&&#"33#"32673267!;%  axXH!0@h?!*!Q(#0j=8Y3I6)4. '  $4)  )9g$k;1;> 5.Rd> "h ~,1;@/0JK2PX@*g_zK _xK` tL@'g d_zK _xLY@32862;3;-+'&! 11 +"&&5467#"&546336454&#"56632332672667#"*!;%7MmF\[3.+F0+X;`x}R'  $6*UK4)  9Z4TAVh ,4ofb x "h F"<(5#.? #@ !"JK2PX@)~_qKrKpK`tL@&~d_qKrKpLY@  # #  +"&54632"&&54677#333267+/*,+I!;%Lt]5%'  $f!*,!'04)  E"K "h ,.w@$,-JK2PX@ _zK_xK_tL@c_zK_xLY@*(#! .. +"&&54677326654&#"56632#"'3267]!;%.H .B",(%?""O38]6&JlE '  $4)  El9//x(YHIf:9 "h *m@()JK2PX@~_qK`tL@~d_qLY@&$ ** +"&&5467732676632&&#"3267!;%("[UN(  YR> '  $4)   OZ r\[R8 "h 6Q"-KPX@ +,J@ +,JYKPX@rK`pK`tLK2PX@"rKpK`xK`tL@drKpK`xLYY@)'#"!  -- +"&&54677#7##"&54673326677333267!;%)  R9GD>C5!6( 0]5%'  $4)  Ee1>UH9'#<9`:K "h "-@#+,JK2PX@(~]rK_xK_tL@%~c]rK_xLY@)'! -- +"&&5467732654&##77#7!#"&'3267Y!;%.Z6?V:FQLB5~l1 '  $4)  )SyrayL69W2< "h AmG5)&f 3+RumGF5)&f 3+3umG"5)&f 3+LG5)&f 3+=ymG#5)&f 3+nGI5)&f 3+gG)5)&f 3+=mG+5)&f 3+XgG/5)&f 3+0G25)&f 3+TgG35)&f 3+1gG45)&f 3+1gGd5)&f 3+Gg5)&f 3+5 G75)&f 3+$ Gn5)&f 3+A:gGi5)&f 3+A`mG;5)&f 3+WvgG:5)&f 3+mG<5)&f 3+AmG=5)&f 3+AgG>5)&f 3+RmG?5)&f 3+RGB5)&f 3+[mGL5)&f 3+:GM5)&f 3+SLG5)&f 3+3gGS5)&f 3+JgGT5)&f 3+[gG5)&f 3+[mGU5)&f 3+agGV5)&f 3+&hgG]5)&f 3+&hgGZ5)&f 3+&gG[5)&f 3+gG\5)&f 3+UG5)&f 3+c&%N3+'&EN.c&% z.'&E K\c&%L 3+_'&EL 3+<&&'z#v3+,&F'zv&'N3+,n&GNl.&' q,.n&G GR&'L 3+,^n&GL 3+'?@< J]oK]pK_tL'% %,! +332#"&'53254&'7'326654&##Hd)IR( "2&-&4Rj4I@8ʋwt* (%2DR(K}WROK,n-<KPX@#( J@#( JYKPX@* ~qK_zKxK`tL@. ~qK_zKpKxK`tLY@/.75.323466773#7#2>54&#"( !2&%%B)$B]:18%p  (I"2$ /#R(A*UFBj@."%0G 4 (%2D]5OQ'/+FV+V3&'J հ3+3n&GJ հ3+@&(73+,h&H@&(73+,%h&H8@&( :,&HJ ܰ3+8@&(Q ۰3+ :,&HQ ݰ3+@&('MLz3+, &H'zM3>&)N3+&INְ3+<m&*L3+ A&JLb&+N3+)&KNFְ3+.&+ .)&K S&+jd3+)&Kjְ3+&+zD)&Kz8"&+M İ3+&)&KM Ȱ3+1&, n9?&LQ ܰ3+&,3+q&'&.v3+i&NvFְ3+.&. f.i&N MY&.L 3+Ri&NL 3+.&/ 9.F&O .m&/' 9L3+.&O' Lְ3+\&/L 3+_F&OL6 3+8&/ l8F&O u&0NM3+V&PNX.u&0 .V,&P &1N%3+)&QN.&1 .),&Q PW&1L$ 3+V),&QL 3+8&1 8),&Q 9<#&23+,J{&R<&23+,,q&R<&23+,h&R<&23+,%h&Rg&3v3+L&Svg&3N3+'&SNH&5N3+&UNm.H&5 Z.,&U .Hm&5' ZL3+.&U' L'_H&5L 3+V,&ULA 3+&6N3+ &VNb.&6  .,&V  &6'3+ G&VZ$&6'3+ |&V.&6'N 3+ .&V&Nb  RZ&7N3+.\&WNYdd3+R.Z&7 &..&W  \Z&7L 3+c&WL 3+8Z&7 8&W EG&8j ڰ3+-GK"&Xjb ڰ3+@1&8 a1K"&X 9E8&8 s8K"&X EE#&8{3+6[{&X/E&8{3+6K^&X/Z&9Q[3+2:&YQZ.&9 @2.:"&Y Z&:Ne3+=G&ZNZ.&: =.G"&Z &;N3+D&[N&;j)3+D&[j[&<N3+;&\NsJ&=J93+&]J.J&= )."&] YJ&=L 3+_"&]L 3+Y)&KL 3+.h&Wjxx3+=GE&ZO;E&\O@,AB&D=3+&@N3+,^&{,^ &{#,^&{ ,^&{ ,^&{,^&{,^\&{ ,^\&{1&$ Ű3+9&$# Ű3+5'$] ̰3+F'$b ̰3+5'$] ̰3+F'b$ ̰3+M*'o$ ΰ3+M*'$o ΰ3+ &  &# & &&&0&(T Ű3+C&(\# Ű3+5-'(] ̰3+F2'(b ̰3+5-'(] ̰3+F2'(b ̰3+)&) &#)&)&=&7&_\&S\&0&+T Ű3+C&+\# Ű3+5'+] ̰3+F'+b ̰3+5'+] ̰3+F'+b ̰3+P*'+ o ΰ3+P*'+ o ΰ3+/?& /? &#/l&y/n&{/&/&/\&y/\&m0/&,y Ű3+C6&#, Ű3+5',] ̰3+F', b ̰3+5',] ̰3+F',b ̰3+P*',8o ΰ3+P*',8o ΰ3+,&R, &R#,&R,&R,&&R, &R0&2J Ű3+C&2W# Ű3+5'2] ̰3+F'2b ̰3+5'2] ̰3+F'2b ̰3+:<&:< &#:<&:<& :<&:<&:W\&:K\&E &#< Ű3+F'b< ̰3+F'b<: ̰3+P*'o<J ΰ3+,&, &# ,&s,&u,&,&{,\&s,\&g0&P Ű3+C'&]# Ű3+5'] ̰3+F'b ̰3+5'] ̰3+F'b ̰3+P*'o ΰ3+P*'o ΰ3+,^&{,^&{" & &")& )&""/?&t/w&",&R,&R" :<&:<&",&n,&",^&{',^ &{'#,^&{& ,^&{& ,^&{&,^&{&,^\&{& ,^\&{&&$&Y Ű3+&$&#a Ű3+5%'$'] ̰3+F''$'b ̰3+5#'$'] ̰3+F''$'b ̰3+M(*'$'o ΰ3+M(*'$'o ΰ3+)&') &'#)&&)&&=&&7&&_\&&S\&&0;&+T& Ű3+CC&+\&# Ű3+5'+'] ̰3+F'+'b ̰3+5'+'] ̰3+F'+'b ̰3+P*'+ 'o ΰ3+P*'+ 'o ΰ3+,&', &'# ,&&s,&&u,&',&&{,\&&s,\&&g0Y&&P Ű3+Cf&]&#' Ű3+5''] ̰3+F''b ̰3+5''] ̰3+F''b ̰3+P*''o ΰ3+P*''o ΰ3+,^&{ME,^&{Lk,^&{&,^,&{,^&{&",^&{QE,^&{&QEa&$Mt3+Mm&$L3+>&$ ̰3+4&$" ̰3+&$`S*%dD@Jt(+D767&&54632 =! ")ES*!!&)7) QS*]3Q+W<` +QdD@Fg g W _  O"!'%!+"+  """" +D663232673#"&&#""&54323"&5432 A)2*? ?)1) E!! E""9>=:H!'H!')&& ),&)&&""R&QJR&&QJR&(o0 ̰3+4'"(e ̰3+R0&+o0 ̰3+4&'"+e ̰3+&+SdDKPXJK.PXJJYYKPX@W_OK.PX@WU_O@We_OYY@(+D767&&546327&&'73 8L!sS*"&3?&U! $U SdDKPXJKPXJJYYKPX@W_OKPX@e_O@We_OYY@(+D767&&54632756673 8LR @S*"&3? #P #VFO\$dDJK PX@+pg gW` P@,~g gW` PY@$$ """" +D663232673#"&&#"767&&54632 A) 2(? ?)1*4I9:=6'.8/&M/&L &t' &"&Q/`&w&,M3+m&,L3+RB',0 ̰3+4F'", ̰3+ThdDKPX@~g_O@&~Ug]MY@$+D&&54632&&'73K43. 'Z!sT4&,- &O! $O TdDKPX@ J@ JYKPX@~g_O@&~Ug]MY@$+D&&5463256673K43. ' @T4&,- #P #VFO\'ȱdDK PX@0 p  ng gX_OKPX@1 p  |g gX_O@2  ~  |g gX_OYY@'&"!"""" +D663232673#"&&#"&&54632 A) 2(? ?)1*//&"9:=60$' :<&MB:<&Lh:C &:[ &'&' &#:J&QB:B`&[&<MJ3+[m&<Lp3+R-'<0 ̰3+47'<" ̰3+C&3\# Ű3+c@ kdDK"PX@UW_O@We_OY@     +D&&'73"&54323"&5432k&p  E"" E""j#Q" $O H!'H!'cF wdD@ JK"PX@UW_O@We_OY@     +D56673"&5432!"&5432* {;# E"" E""j V !N'H!'H!'"^ ,dD@!JU]M +D&&'73]!u^&O! $O ,&&n,"&,&'",&Q,&'QR+'02p ̰3+4'"2M ̰3+R@&v0 ̰3+4&S" ̰3+ &,^ -dD@"JU]M +D56673,# F^ T "T T' UdDKPX@~mW_O@~W_OY$+D&&54632 64-$-T3)+1"{t@U]M +3*{m!@  Ht +'7'77'>RRSSRR>>RQSSQR>d{ 4@1JHU]M  +3'7'7#@ll@y=kk=H+{ 4@1JHU]M  +#'73yAmmA=kk=!$$@U]M +7!$$pp\'_~_h$@!]oL    +&&'73!&&'73m3~9 @13~9 @1{Z$@!U]M +3#迅'H,{Z$@!U]M +#53'!{t&@#U]M +#53#__b{t 0@-eU]M  +#53#3#__b'&{t 0@-eU]M  +#535#53#__b&'?'&WgZqE #/K#PX@+ g_wK _rK_ xLK)PX@( g c_wK _rLK2PX@& g g c_wL@,g g gW_ OYYY@#%$ +)$/%/##    +"&54632"&54632"&54632"&54632(--('//'(--('//'(--('//'(--('//C'')%%)''''(&&('''')%%)''''(&&(''{t5@2eU]M +#535#53#3#______b&''&{t 2@/eU]M  +#53#35#__bb{u%@"JU]M +'3``}{u@Ht +#7#`uu`b{u @ Ht +'77'`uu`>>>sYkkY777{t 3@0eU]M  +#535#533#_____b&'&]U1@.gW_O  +"&54>32'2>54#"@J/O32&&#"36632'2654&#"DQ9fO:  )-60!77+N4 " WU&^V7\ #5@22N-U. # [T(J@G JggW_O$"(( +"&'532667##"&54663272654&#"( ,1<" /!77+N6KJ@y"#[3A11O-RFXI+.CFD̠)&f 3+&FH̠)&f 3+,FR̠)&f 3+EF[̠)&f 3+F&̠)&f 3+8L!G@D  Jeg_wK ]  p L!!%& +37"&54>32&&#"7!#3#3*[^"DjH1F.0:Q$'fZ>v_9 r ha/+pIpVr s'29O@L40)&$J~a]qL(((2(2.+''#"! +7&&54>7733273&&'667#7&'7&&#""'V/14*WYJ " J)9/G1J$#  a.=:v mGDvP JJRh y  LL XlGCUc-*"h0KPX@  .-*#J@  .-*#JYKPX@W_wK_xL@g_wK_xLY@&$  00 +"&54>32&&#"336632&#"667z;XyLD_/:"I-9S6 Ab =& *7d ?u]5z<`q49I1X-4} .2\  V/KPX@  "J@  "JYK PX@"no_rK pLK PX@!o_rK pLKPX@ _rK pL@$rK_zK pLYYY@//%$"$ +333663273632#654#"#7#7654#"tp  S9,8vdMDD AC0"5( / ed 0"5' 0"e1>$!uUH$4?#<8_;+x5#<9`:L#'+]@Z( Jf   eoK  p L+*'&%$#"!  +37#737#73733733#3##'#3'#3'#37#37#477765M5s477774W4])@/$ 6 JHJJHJkHHHj  <@- . JKPX@+e]oK _zK]  pL@/e]oK _zK pK_ xLY@20+)<< ! +332##32654&##"&'532654&'&&54632&&#" ksK;@15:T8E'/f,I E%0++/eX+P&0:!$+7q_cQk;9(%y >4Mbi!?8^`"&*.14h@e"J  f   eoK p L4310.-,+*)('&%$#!  +37#737#73733733733#3##7#3737#37#37#7#7#J RG;0 mX^z WZp[1=HT[X^ +@=%*@! JHJJHJ\HHHHHddd3@0JfoK pL +3#7333733##@IIBD xc_I=5/a:3a!"'Z2@/ J]oKpL +37'77'77#7!#77T Y!*\!a!/v4;TX7;W~~]9;ZX<;\/<@:*JKPX@7  g_wKrK` pK _ pK tL@4  g_wKrK^ pK _xK tLY@10750<1<//(&!%&! +33326654&&#"'6632#6632#"&'#2654&#"tZOm95_?+[$-&y=rRft;Rf[[R%SF"3  "2 "*  $"WNS8U/pN]ceX[F-X:E-@6."&15 N'3C@@"  J_wKpK_tL/-'' +"'532654&''#7&&54>326654&#"! %" 0Id,O'@M&FP.J,m"/) sC7 I+d`Jz5F\6SE;f`1C>ol-h$=@9\!'-V@S e  g ]oK] rK p L-,*('&#"!! +3#737#737323#3###3&&##3665#3267#K66 66"bb</.9#q(u"3$$(<~cE;E[GEEMV( <!'L@IJewK]qK_xL'&#" +7&&54>773&&#3'6677#]g-XV W_U8$H+*O.fJ*_8K%$y! EPMtS{Q ($,{F`y<9Ms"J@GJ f   eoK  p L"!  +#7#737#7333#3##'#3&&53'#n4 R]JHJJHJ?&EHN5^@[2 3 Je   e_wK _ xL0.*)('$#"! 55 +"&547#73667#7!6654&#"'66323#3!3267ln 0I7A(%#C0*6a==Z2 /PC(.+4S6,d iP'!J$ J #u-Q6*#J!J$"%~<%-@*  JqK_wL +7&&54>773&&'667'fh+X^W)E":7e"D#T6,c/E,'PJrLU$'z"  G BZd/?ME;JK*PX@/p~ eU]M@0~~ eU]MY@"" +37327#73&&##7!#3#͈Ck)+F]Sdh0]IJ&hJ3JAY Z<p pp3+1$/7X@U ~gge W _ O%%7520%/%/.,(&$$  +".54>32'26654.#"'32##532654##Pc67dNLe96cPRP-Pm?VNM/RLV>RF#+OE 6cPLe96cPPc6@NY?nT/NYYNTEDCL#'F 9@* + JK PX@:   ~ ~e  gW_ OK PX@3   ~e  gW_  O@:   ~ ~e  gW_ OYY@$/-(&99   +333#'#73'&45"&'532654&'&&54632&&#"ss;i.Yl'M@96."0M>;0#%Q6rXJJS O   -'4: I   * <:" .@+eU]M +#737#7373)tppGW't'{~u`~3+`3+u'&tub3+b3+,!<@9f eoK ]  p L +37#737#73733#3#3/VVVU55VJTTJVa}X5@2f eqK  p L +37#737#7333#3#3JJJJ::LLLL3TLTTLT=@:JghoK^ pL"""" +3&#"#663233273#"'3E JP1 =G !JO1 !FRD!5RE}gkK,PX@%e]oK]rK pL@#ee]oK pLY@&! +3#73732##32654##3#\KL&Wi/RXL5P=CR_F gha4^>Up7zB:X7aH%I@F Je]oKpK_tL%#  +"&54732##326732654##GRk}ZCe:F 5F&@G`$@A\hUk r }89P0O",KPX@+)J@+)JYKPX@& ~qK_zKpL@. ~qKrK_zKpKxLY@$##,$,( +"##7&&54>32733#7#'#"2667654'fat&$B]:0!tan`tnK9/#?4% SBCk@G$- +FV0K+$.0!"R@O!J eqKrK_ xL  " "  +"'#7&547#?3373#32677gVy8J`@_;mVy %C+ 9H)stZ n UU0<D!0@-aqK_zKpL!!)$ +7#654#"#31366323*_C5"5' 0 J1FG *PA?#<9`:60%.UH$40.@+ JaoKpL +7##37733~-#g=5KLʰ\[H!"f<i2@/ JbqKrKpL +7#'#33733X*%Y;$HݨXOA#B0J +@(]oK]pL  +7!7!7!!-{#Gb}c<" +@(]rK]pL  +7#7#7!3*nBXXrb<(KPX@ JKPX@ J@ JYYKPX@_wK_xLKPX@oK_wK_xL@!oK_wKpK_xLYY@" ((  +"&&54>32373#'#'26776654&#">[31\S.=)"|(X Mb7>4O6: @tM\O,V6V,4o+&#ժ z(Z''V"p'O)*b"AJv'= `(OPB=l,1W@ +JKPX@]rKpL@rK_zKpLY@11%+ +333>73366776632&&#"#'4667#Vq 0 G?'  r"(O.=2 "F)%S-hFN s '&<>;7U, ,e@JKPX@g_zKpL@grK_zKpLY@(& ( +3'#7267&&546632366736654&#"60+D&4CD8   s  R*54&#"G]U^9A)!6aZ\bS79H"" hjEV8vE49`br`g\y Ll7&1'/JB0+7'%'%4$$$$5555}1@.W_O +3'"&54632@]$$##}Kh&^ *@'J GW_O  +"&54632'7$$##BBBB^^ 0@-gU]M      +"&546325!)$$""K]]xSFK PX@nU^N@U^NY@ +5353x5S5qH@Ht+5#7#H:z@t+'3533AL:UHEe1@.W_O +3"&54632/cN$(#%$ X &) $,ER5o 4@1~W_O      +"&546323$(#%%c[/ &) $,jX$we e3+S BK PX@o]qL@]qLY@  +7!##7#0# ]5BS5qqqAm BK PX@n^pL@^pLY@  +#7373373 ]4C5#5qqq.OJS а3+9 (& FPF3+3+/@,eU]M +7!7!?lllhjjkkI<@]oL +73IM}#`r@]oL +3`(]rXWq  dJK PX@_oL@_wLY@       +56673"&54323"&543229< E!! E"" H" 2/H!'H!'Wq `JK PX@e_oL@e_wLY@     +&&'53"&54323"&5432BB  E!! E""F# "A" H!'H!'Ke$@!W_O+667"\߃^?Kg^c21PK$@!W_O+&&'72AqkK+7cea_[ .@+JW_O %"+6632&&#")~B8[*5b:">_NKf E` 0@-JW_O   +"&'7326735\+3c<#=K(` f MK,^z&{a,^z&{a,^z&{a,^z&{_,^&{_,^&{_,^&{_,^&{_/z&/z&/z&/z&/&/&/&/&:<z&^:Fz&^:<z&^:Fz&\:<&\:K&\:<&\:A&\/&/&/&/&:<&\:<&\:F&\:F&\.%h@JIKPX@c_#K$L@c#K_*K$LY@%%+"&'53267654#"#336632U*(0<WW0U?K} *gJ6T0 ]{|;@%WAoDs5I/V:!*H{j. P+{IKPX@*~_#K_#K`+L@(~_*K]#K`+LY@"  +++"&5473326776654#"#336632Bu}mEN'W0T>O} *gJ6T0 ,L s["" WQD WAnE ts5I/V:!*Pv@oUzKPXJKPXJJYYK PX@gU]MKPX@g]5LKPX@gU]MKPX@"UgU]M@#egU]MYYYY@( +767&&546327&&'737! 8L!s>*"&3? &O! $O {]]mUzKPXJKPXJJYYK PX@gU]MKPX@g]5LKPX@gU]MKPX@"UgU]M@#egU]MYYYY@( +767&&546327566737! 8LR A>*"&3? #P #V{]]qUzK PX@Wg b7LKPX@"Wg7K ]5LKPX@Wg b7L@'~ge b7LYYY@$ +&&54632&&'737! 43. 'Z!s>4&,- &O! $O {]]pUzKPX@  J@  JYK PX@gb7LKPX@g7K]5LKPX@gb7L@egb7LYYY@$ +&&54632566737!43. ( A>4&,- #P #V{]]^f'N'v^3|'NK3+^ ^ ^K"PX@g]oL@gU]MY@     +"&546323"&546327! #&#$##'"$#>#%!'#%!']]]q -G@D  g c_wL --+)'%#"     +"&546323"&54632663232673#"&&#"#&#$##'"$# C--&K B.*%#%!'#%!'@>C;],{ D@AJ d_wL   +56673663232673#"&&#"!6:> C--&K B.*% @! .-@>C;Uh zJK PX@eU]MKPX@e]oL@eU]MYY@  +&&'537!AC#>I" "A" ]]Uh JK PX@U^NKPX@]oL@U^NYY@    +566737!DAD> I! 41]]W1r)h JK PX@ _oL@ _wLY@%#)) +&&'536673"&546323"&546323O/9Y65#&#$##'"$# H *& .0#%!'#%!'WWXK PX@e_oL@e_wLY@  +7!"&546323"&54632;>#&#$##'"$#]]#%!'#%!']W;@8e c_wL  +7!663232673#"&&#"C> C--&K B.*%]]@>C;WWJK PX@e_oL@e_wLY@  +7!"&54632>> $ !!]]#%!'-/@,eW_O  +7!"&54632$> $ !!]]#%!'wM $0JKPX@*n  h  _ 5L@)  h  _ 5LY@&&% ,*%0&0 $$   +56673"&5332673"&546323"&54632,j .2RBH$//8 Ia#'"$##&#$#Y : (( PU&-0#J[#%!'#%!'wM #/|JKPX@$n h  _5L@# h  _5LY@ %$ +)$/%/##  # +&&'53"&5332673"&546323"&54632-3 g@RBH$//8 Ia#'"$##&#$#Y<6SR&-0#J[#%!'#%!'wM &N@KJ f  _5L " &&    +566737!"&546323"&54632,m .2>#'"$##&#$#^ :(& y]]#%!'#%!'wM %kJK PX@nf _5L@f _5LY@ !%% # +&&'537!"&546323"&5463253 g>#'"$##&#$#^<5y]]#%!'#%!'xD)KPX@ J@ JYKPX@%W g c?K 5L@-~g e c?K 5LY@'&$" ))$ +&&5463256673"&533267343. ' @bPIH'.1/I^4&,- #P #VC@;HxD)KPX J JYKPX@ g c?K5L@% eg c?K5LY@'&$" ))$ +&&54632&&'73"&533267343. (Z!sPIH'.1/I^4&,- &O! $O C@;HxD&KPXJKPXJJYYKPX@ g c5LKPX@ Ug c5L@! eg c5LYY@$#!&&( +767&&54632756673"&5332673 8LR @lPIH'.1/I^*"&3? #P #VC@;HxD&KPXJKPXJJYYKPX@ g c5LKPX@ Ug c5L@! eg c5LYY@$#!&&( +767&&546327&&'73"&5332673 8L!sPIH'.1/I^*"&3? &O! $O C@;H "KPX@J@JYKPX@]#K]$L@]#K$K_+LY@""+"&'532667667!73##'#($ (&E,NKTIm('!CR |77D uLy+U]#p,'KPX@J@JYKPX@_,K]$L@!%K_,K$K_+LY@  ''+"'532667>3273#'#'&&#",*"0@bJ68ww=@ (1%!,? y/N.EfB!.ZC2XC&:@7 Jg]#K$L#!+33273###32654##Wi/g*yG*5PCR_$4^>F%#zB:XZ,-|@ JKPX@]%K _$K'L@'%K_,K$K _+K'LY@ '%- -$$ +33663273#'#"&'#2>54#"!pN<"C,wEAV426 #/#@$2 %S#:!K?8Y5."(B&]+FV+V4NR'/ZJ@GJe e ]#K] $L' +#&&54663!#3#3!#37#"=-3@`!'{:95)B=B=AIg   g _,K ]%K_ +K_ +LYYYY@#BAECAIBI?=:820+)%#  77+"&'5#"#"'53267667&&5466336632##326732654#"37#"1ep $>4,  &!,@l@ = RY3.+F0+XpUK6,I->$0" id)>" , y*) 6/AR&TAVh ,4oF3#0@S)%!-@*  J#K$L+337'773'#G8O*MEP6BJ`1FYs1ZL_"-@*  J%K$L+337'773'#u6z0M%9?O3(9"~K39;`3N* 9KPX@-! J@-! JYKPX@)g]#K_$K_ 'LK2PX@-g]#K$K_+K_ 'L@*g c]#K$K_+LYY@1/,+%# 99 +"&'5326654&#"###"&'532667667!6632|*I@%6P+GB$ 9}('!CR8$ (&E,F,,WF*&Ny  =iCPTLLy+U]#|77DAiKFk@ ,;KPX@01"!J@01"!JYKPX@)g_,K_$K_ 'L@-g_,K$K_+K_ 'LY@53.,%#  ;; +"&'5326654&#"#&&#"#"'532667>326632@56@*,'\(1%!,?/*"0@bJ2Z/#\^@q  9[15>.ZC2XC& y/N.EfB! }b7ue>*@ JK2PX@(f  g#K$K_ 'L@%f  g c#K$LY@"  ** +"&'5326654&#"###3336632*I@%7O+GB$ 9AA;;F,,WF*&Nx  =iCPT4AiKFk@ "'K PX@J@ JYK PX@'V h%K$K_ 'L@(f  g%K$K_ 'LY@! '' +"&'5326654&#"#7##33736632@56?*,'/0u-,4#[_@p  9[15>"}b7ue>0 *@'a]#K$L +7###!3-}} ~FL<e,\JKPX@a_%K$L@a%K_,K$LY@$$+7#654#"#3366323.~C5"5' 0tp  S9FG 'nC?#<9`:"e1>UH$404@1Jga#K$L#%+7#76654#"#366323-5K&G#D:$Y-,Q3F  @E: <e!0@-a_,K$L!!)$+7#654#"#31366323.~C5"5' 0 J1FG 'nC?#<9`:60%.UH$4cF JK PX@oU]MKPX@o]#LKPX@oU]M@U]MYYY@ +'7!#'##'#  8" @"" @"cT++T2222 !?@< J~oK`xL  +"&'??3776673'GBXYYY&0Oj .WCW2W2B1W2Wa +@(oK^pL   +33333|}6},u#;@8JcoKpL ## +"&'53267>7####333$ !'1 ? F  ϓi}8D*"MK)IV)Jzn&KPX@! J@! JYKPX@~_wK_xL@#~_wKpK_xLY@ && +"&'532654&##57&&#"#66324R" R(:IGJ 4+AH\`Pk; ?L 96)3_}$QPLČ;]4sYItv`$ ʰ3+B%Y@ J HK#PX@~rK_xL@_xLY@%% +"&&54667326654&#"76632OMzFL]wT{C@:4@( $ .OY+Pp =y[o 9.gjDS5U101x lfBx\6 2@/ J]oK_xL  +"&5466736673'3267}:3/Q1M{G(B'18F->@;JfcoKpL  +"&'53267##333S+ .'8A;;j|@= M}mR&7 3+g$P@M !"J~|_wK`xL $$ +"&546675'7732&&##"3267 Ck<9y.BN#q5:W1F:0X5/b qVF^1_by(%f"Bqk0,-/};@8JeoK_xL  +"&'5326777337667#,'' ffi~ " |.-rq}meP 9,^*X@UJfoK_  xK_  xL  * *&%  +"&'53267!733#37667#7>73,,' fMi~ "p 6" |:7rqt}meP 9,* => &Y.&$$.@ JKPX@!f_oK _xLKPX@%f_oKpK _xL@)foK_wKpK _xLYY@! (& .!.&# +#36632#"&'#31'.5#26654&#"<v /[,[bhT   Z:`9=?!Lʰގg=5 ~AA~f!"-@*  JoKpL +337737#''7'KLʰ+Y/hC!M.\'=5fp9KB]0K;n";@8 JfoKpL +3#73733#7737#''7'o65>?!Lʰ+Y/hC!M.\'=5 ~AA~fp9KB]0K;n"gV (@%JoK^pL  +371373X @6 G23,23} -@*foK]pL  +3#73733#3oIHZZT ~AA~r} )E@B e _wK _xL"!%$!)")  ## +73>323##"&547"!654&267!,\c6-[fl@c5=@hB4rRSyrWV{#cNBOeZGJ<*9 JK PX@" g_wK _xL@, g_wK_wK _xLY@,+! 31+9,9'% *!*  +"&54>326632#"&'2654&#"26654&#"E-]bH`B/19-H*^2* (:`9=<.O9 B {TQ+""*'@%>^4 o\=4C.1SfBO5^yEGJ< :g9@6ee]oK pL&! +37#7332##3#32654##CCmWi/RXL ]\P=CR_FI}4^>Up78}IzB:X%8@5~g]oKpL%# !&!& +7&&54663332###7#"%32654##+\JGWi/RYL56!=CR_F7U1P4^>Up7( B:Xb,4KPX@ JKPX@ J@ JYYKPX@h_wK pLKPX@$~h_wK pL@(~hwK]oK pLYY@42/-,,&!)%)! +!7#"&54776654#"566323332##32654##26\m 8">6P GWi/RXL5P=CR_FeR%- i70$* IO4^>Up7zB:X6O)<@9J_wK_xL#!))&# +'7'#"&54>327#''26654&#"0!X -]b0cLg"X8H:`9=<.O9 BQ$2{TQy\$)Q#W SfBO5^yEGJ<.Y'6?@<'$J_wK_xL)(0.(6)6&%&# +'7'#"&54>327>54&'7#''26654&#"# -]b0cL**10AMMB:`9=<.O9 B4SA{TQy\$.*; 54#"'66323733##7:D5,H#aJG\$L.0c/JD1MK/BM@  JKPX@oKpL@oKoKpKpLY@  +73336673#'m+B Қ 7  }4O!G"6hqZ1?@<& JoKpK_tL,+! 11 +"&'532677&&47##3366733667392). "  $/;P 4#W+:.PBz&\''Yp6=)_"B3[F'%=@:f  geoK pL&! +3#73733#32##732654##vIJ bb 0Pa+KQG*.>LX70d66d<0V9Ng2N;6QA=@:  heeoK pL&! +37#73332##3#32654## MMu0Pa+KQG __ F.>LX7>d(P0V9Of22d>F;6Q%@" JoKtL +77'7!>73S[J<]8  !#"LV((VV(Z#45w,h(VJ)D@AJg_wK_xL'%!  +"&'532677#737>32##32654&#"P,.(  aIBg;e}m5/=&YN$9@6Jg_wK_xL$$%%%& +52>54&#"3267#"&546632>hM+&1#5)! 3P]AzTvpm w$Ui7D)D*(+c jWQI}k<QK,PX@]oK_xL@g_xLY@  +"&5467#7!2'26654&#"E;BpR,[W:`9=<.O9 B {YLyWOSfBO5^yEGJ1{KPX@ J H@  JYKPX@f_oL@foK_wLY@%$ +336632&&#"3#p !T5  7W ]e4;WV6~I+K -2@/*J]oK_xL%#   +"&&54667&&5467#7!#"'32654&'5^;4\:&w}"" 5>;t**6;) +Q99^C*#1zz 4h733#7## H~fF-y GCHR->A%E@B  Je_wK_xL%%%$%# +73>32&&#"3#3267#"&5471]dC`/:#H-5P8CI)S)dA-~OSz/N/~ QP 'E@BJe_wK_xL$#"! '' +"&54777>32&&#"%32677#7!D|25ifk]8$H+Ji" DL%I1m -*ZP~I0{G7DZF12PSt~)@& JoKpL +3777317737#5OOOKLʰyg=5Yuf$Z"!" ,@)   JoKpL +3773737#7'36679NNK`v=8RRLcz=g M0I Y c Z 44E" T(  B@? Je]oKpL% +3?327#'#7&&#3267UON/h{ Q= O9w[J4} 1,G2K Z PN Z H\NN&(-=@:(&%J_wK_xL -- +"&'532654&'&'77&&546632&#"76Y,V-1C0& X 323732>54&#"Dc12g3L]  V:$I=&,TwK@Q&q;Rf/J3333L171F($&-=bEK~M92`BOc6@eq11G6[l6EG!v JKPX@& hoK_rK] pL@$g hoK] pLY@!!$! +3#"&54632733#3376654#"_B@9F3 +E]^'"6;):= M}#o. ʰ3+73 ʰ3+$y,@)JgcoL#($$ +&'#"&546323%3267&#" D(;EEE!    =47O /+#/;f% #KPX@ "J@ "JYKPX@~wK_tL@~wKoK_tLY@##%$%$ +&&#"'663233267#"&''v,  7A: "ɧ: 2!C> #'r 36;%s =@c#?@<Je]oK]pKtL#!,! +32##32654##32654&##f|RJ1:JOj3I5ASJcX7C,-QJUI^ E5Qg1+1C/74&)A 8&$P@&(P&,P,E&8P&/ &1 {" /@,e]rK]pL  +#737#737#7! )t^]y]"'")Y~,,0:KPX@ .J@ .JYK PX@'pg_zK` xLKPX@(~g_zK` xL@3~g_zK_ xK` xLYY@8631,*#! 00 +"&54>32##326732654&'3#"&'32654#"`x'MrK[\2/+F0!] 5*( 'QhUK35) hkEd;TAVh ,4&,>5  F5#."< , ,8[@X .'2(Jge_zK_xL,*%# 88 +"&'532654##732654&#"'663273267#"&'8`![54JVV=>?!*!Q(#0j=Fg &<#/@(=()4 y)9g$k+1!3.' S7> &  5.Rd,,(1M@J$-Jg_zK_xL*))1*1"  (( +"&5466774&#"5663273267#"&''2667W\D])2,)C/*V9Ws !;#/?: J{H3'! PA8H/ 72o[\$3.' U7> NNj&B)A+"@rKpL +33tt""&'P"+@(JrK_tL  +"'532673+3"- | .P v (+G2R1/@,fqK pL +3#73733733###zLKKJzzz@cUUUUc@"3@0 " J_qK_tL#*%% +7'776632&&#"7#"'53267,z.dP"9' !J,S .P=3"- 322654&#"62776654&#"=_5$HmI_p"Gm8$9"+!1$!6 3^AHc8rfE~b9>K,:&?K%xhFM̠)&f 3+#KPX@ J@ JYKPX@~qK_xL@~qKpK_xLY@## +"&'73267654&#"56632#7#  7W6  - >Jvp !T WVw KD!e4;6"=@:Jf%K_'L +"'53267#73733#,3"- 9LK//KK= -O v (+ aa2R1R"8@5h%K_'L  +"&5463333#'267#".>B[QuuJJ /MD#>,@F"M/J*R&+ gG)=)&f 3+")F')&f 3+"d@ JK2PX@~%K$K`'L@~d%K$LY@ +"&&54677#333267!;%Lt]5%'  $4)  E"K "h 0g K PX@ noU^NK PX@nU^N@U^NYY@ +7#73733#A 1 1`1 1 ::gG1=)&f 3+n9"&'Q ܰ3+."&' />T$@@=ggg_ pL$#!$! +732654&##732#732654##732#u '+:A37'O=\ ((/5+1"D2G5*#a7'7732&&'#"3267Ps<.IV)!=\+/$N&qc{D8-V-9B:e@9[C'qbhp 7jIM3:{  ":@7  JrK]pK_tL#& +#731#"'532677'37>7#,ti .O>3"+ { !r h4S0 v (+%uf:1 /2" *Z@WJrK^pK_  tK_  tL!!!*!*&%  +"'532677!733#37>7#766733"- tZ .O{  "h# 6! v (+%rTv94S0fq:1 . "b% &W/" )@&e]rKpL  +3!#3#s0-"_^-&7@4J_zK_xL&& +"&'532654&'.54632&&#"*E"C#&3%+gVRD)5($ .-8^ h%*9%I_%X""H1:L%-,'7GKPX@  $!J@  $!JYKPX@  _zK ` xL@(rK  _zKpK ` xLY@'98)(B@8G9G1/(7)7#"  '' +"&54>323736632373#7##"'#7#7267654&#"!2667654&#"DS$C\72;\ =+, qtn4(B)\F+? "."$Y4%%/# eaHh<)'F,,$FG)(8.G$-wX>..'/+FV+/'0K+$.#-+FV+V,W,$4BKPX@  !J@  !JYKPX@ _zK  ` xL@&rK _zKpK  ` xLY@#65&%=;5B6B.,%4&4  $$ +"&54>323736632#"&'#7#7267654&#"%26654&#"CT$C\72<\ B/3R/"DgE1A\F+? "."$^)9'0 eaHh<)'F,!3aDE~b9.G$-wX>..'/+FV+/'Bi;)7-HR%Z,x,)9KPX@  &#J@  &#JYKPX@ ]rK ` xL@%rK _zKpK ` xLY@+*31*9+9%$! )) +"&54>323733266773#7##"&'#7#7267654&#"CT$C\72<uC5"5' 0tp =) ,\F+? "."$ eaHh<)'F#<9`:e1>.G$-wX>..'/+FV+/',, 0KPX@ J@ JYKPX@]rK_xL@"rK_zKpK_xLY@"!+)!0"0   +"&&54>323736673#7#72667654&#"(F,$B]:4Aq6 %ī_K4%$ /# 'WHCk@,$F68B&G$-w0K+$.#-+FV+V(,)4KPX@ J@ JYKPX@"f]rK _ xL@*frK_zKpK _ xLY@0/$"))  +"&&54>32373373#7#72667654&#"%6677#(F,$B]:4Aq|X_K4%$ /#% %'L 'WHCk@,$F||G$-w0K+$.#-+FV+V#B&7#68,,.>KPX@$ J@$ JYKPX@#]rK _xK_tL@'rK_zK _xK_tLY@0/97/>0>+*.. +"&'532677'##"&&54>323733>732667654&#"" .C P8(F,$B]:4Aq;  ǫ00l:4%$ /#u<(S*5'WHCk@,$F8:12&yCH]0K+$.#-+FV+V,i7@4JfqKrKpL +3#73733#373#'|NM~~"ݨY;$GbOObB#i1@.  JqKrKpL +333737#''7'HݨB0NI<.I;$BB1C:F,B6;#i?@< JfqKrKpL +3#73733#3737#''7'|NM~~"ݨB0NI<.I;$GbOObBB1C:F,B6;#[ "@JqKpL  +371371TRB ^224Dq '@$fqKpL  +3#73733#|<;<;|GbOOb,!)E@B e _zK _xL#"&%")#)!!## +773>323##"&&547%"3454&267#BInJ_pLBGoN=_5'6a(8jAg:rfjBj>3^A >, )7@2 Z,,(6 JKPX@" g_zK _xL@, g_zK_zK _xLY@*) 1/)6*6%#( (  +"&&54>326632#"&'2654#"26654&#"=_5$HmIe68%<;(D) Fp#)9'!2  3^AHc8> H48S. Cm?S, ,/*Bi;)7-HR%Z,s, l',-@  JKPX@' f _rK _xKtL@+ frK _zK _xKtLY@ '%- -'$ +73336632#"&'#3##72>54#"\KpL5'G,$B]:26!/#@$2 %bbS#:'WIBj@."F@bNN+FV+V4NR'/,+;@ 9JKPX@- ~g_rK `xKtL@1 ~grK_zK `xKtLY@-,42,;-;+*2'$5 +&5466322336632#"&'#&"#"%2>54#")(VDRpL5'G,#DhE#8 ; !"\!0@(",B 5X4S#:'WI;oE (B%k) +GT(V/2 )1,8CKPX@(#J@(#JYKPX@_zK`xKtL@"rK_zK`xKtLY@B@;:88'$%. +7&'&&546776654#"56632336632#"#>54&#"40$5>  9#7<$(YpH9'G,-[] 0n%P\'24 fM6#l99 $01: S$9'WIKf:Cl>++T,A,!1KPX J JYKPX@' f _zK _xKtL@+ frK _zK _xKtLY@#"+)"1#1!!'( +73>1##"&&54>323733##72>54&#"| D3$C,$B]:1>qDC#1$ /#$b/+"1'WHCk@*&FbNN5OQ'/+FV+++,,+;@+JKPX@&_rK_zK_xKtLKPX@$g_zK_xKtL@(grK_zK_xKtLYY@-,53,;-;'( +'7661##"&&54>3237376654&'7#7'2>54&#"{& D3$C,$B]:1>qNl!**! ;A20D!##1$ /#$,!"1'WHCk@*&Fd6% ;B+3K15OQ'/+FV+++D"/@,Je]rKpL!%! +!'#7326654&##'32Vip1 &%?|VgP>id# iLGMPu,$B@?  J~_zK^pL$$%( +#77>54&#"'66323733##7.0, A+^A5C!F;K<=a+3$^!2&?$"@M5Bu:0@- JrKpL +37336673#'|/ yB  ٞH] CA"8=G"2?@<( JrKpK`tL/.$#22 +"&'5326774667##33>733>773A# (6 rqk%mu4,<>;7"(O.=2 "F)><OQ' 2@  JKPX@-qK]oK _zK _xK tL@+fqK _zK _xK tLY@"!*(!2"2 &% +#73733#3632#"&'#2>54&#"!DDll ?KDV=\>2> #/"% 0"!CbCCbCSbe54&#"RC  ?KDV=\>2>  /"% 0"!b2 LSbe773!< C2 .21/ ,*D@AJg_qK_tL(&"   +"&'53267#737>32##32654&#"%&-'K 9eOCS'H~P5Po518 $*x9Hey49gA-M.Of1yq5.>&2$-&9@6Jg_zK_tL&&&%%% +526654&#"3267#"&54>32dRS&5!3( #U`&Fb;Tg.>tsSAV/N.71m q^>pW2HVpK,c#2KPX@   JK'PX@   J@    JYYKPX@-  ~qK _zK ^ pLK'PX@9  ~qK _zK ^pK ` xL@5  ~qK _zK^pK  _ xLYY@!%$-+$2%2 ## +"&&54>3234667733733##7#7#72>54&#"(F,$B]:18%)P[PgQ[Qu K "2$ /# 'WIBj@."%0{sG$-w5OQ'/+FV+Vc 2@/~qK^pL  +333733##7-P[PgQ[Q{sc ,4  JKPX@*  ~  _rK^ pL@.  ~rK  _zK^ pLY@440.*)%#%$ +3336632366323733##7#654#"#654#"tp  S98> V9DD ))P[PgQ[QC0"5( /C0"5' 0"e1>;41>UH$4ěs?#<8_;?#<9`:c,"yJKPX@'~_rK^ pL@+~rK_zK^ pLY@""$$ +33366323733##7#654#"tp  S9FG )*P[PgQ[QC5"5' 0"e1>UH$4ěs?#<9`:KPX@ JK"PX@ J@ JYYKPX@$oK_rK_rKpLKPX@!oK_zK_rKpLK"PX@!_zK_rKpL@'rK_zK_zKpLYYY@#! +33366773&&'#7tp 'n>K[K1(FM\K:V7"e19 GGc"!L@IJ  ~  e ]rK^ pL!! +3323733##7#'#326654&##tVgP>3|PZPgQ[QV3+@:1 &%;"LGMPks/# .V)3KPX@ &'J@ &'JYK PX@+ p _qK_ rK_ xLKPX@,  ~ _qK_ rK_ xL@0  ~ _qK_ rKpK_ xLYY@20,*$" )) +"&547#?337>32####326732654&#"@N8J`@_ 3VAJTng-\\8%Cz %*. 7GH)st6W3LAWiO  n ,$ I".1@.& J_wK]pL-+"!/! +#7326654&''7&&546632#7654&#"5: S 1S3;J#*'!#AtNK1s/"f'N#32326654&#" 11@!EkJDg9>tQH 0;).):*d((hI3dQ1/Y=MwD71ir/K,&/0K+),"@rKtL +3!X,&h@JKPX@_rK_xKtL@ rK_zK_xKtLY@&&($($ +336632327#"&5477654#"!p  S9FG (4GM 5"5' ce1>UH$4# qD<#<9`:.,iKPX@ J H@  JYKPX@_rKtL@rK_zKtLY@ %$ +336632&&#"#p !T5  7Vie4;WV,"5@2J]rK_xL  +"&&5467#7!#"32679\6]K&=_B#,(%?"#N 'O>T(ss,GQ%+.x' -O@LJg h cqL"!)'!-"-   +"&5477#"&5463233#327376654#"GM.@9G6 9S__,(2"fD<;):=  yM# q#<H,\JKPX@a_rKpL@arK_zKpLY@$$ +33366323#7#654#"tp  S9FG (RC*]C5"5' 0"e1>UH$4?#<9`: ,%E@B  Je_zK_xL%%%$%# +773>32&&#"3#3267#"&&547CJlF1M"-3 +?uu,(%?"#N39\6cBf;p =/c //x(YHb,,5?KPX@ ;:10, J@ ;:10, JYKPX@"_zK_xK_tL@&rK_zK_xK_tLY@76.-6?7?-5.5*%(% +'77>323737#"&'532677>1##"&&5"7454&26672 Ce?5=q'HH=KkC=P%&U/3@ D3'C)'=$\, %Z KQ+%FZVc*/2%"1)UAQ9# '/&>$#++i-@* JqKrKpL +377733737#')CCeHݨ׷pY;$ Z BZ#k, ]@JKPX@_rKpL@rK_zKpLY@  $ +37773366327#7"7654)<<8p  S9FGFD72.&; Z e1>UH Z J:<,qKPX@JH@JYKPX@_rKpL@rK_zKpLY@ %$ +3777336632&&#"7)NN8p !T5  ,J. Z e4;77Z,*=@:%#" J_zK_xL** +"&'532654&'77&54632&&#"75M"%N)#6)Qnb/X*0A &)> } yZ !/UYiZ '^`Y|+5, O"" "3+,$3@0JH_xL$$ +"&5&667326654&#"76632kw`}7by?,'.   FS@u ss˟0R5zzm*?94M'&6taY\N;",@) JrK`tL  +"&54667336673'32677B:b3"- di -O v (+G))cO m ' )cO m ' p2R1 v (+2R1AMQK.PX@#$ 65J@#$ 65JYK.PX@<_qK _qK ]rKpK _ tL@9_qK _qK ]rKpK _ tLY@1NNCBNQNQPOIGBMCM=<9742.-,+(&! AA +"'53267#?6632&&#"376632&&#"3##"'53267#"&5463233"- dPY cP"9'" cP"9'"kki -O>3"- di -O~ */*,+tt v (+G))cO m ' )cO m ' p2R1 v (+2R1V!*,!'0"AEK.PX@#$65J@# $65JYK.PX@._ qK ]rKpK _ tL@2 qK_qK ]rKpK _ tLY@)BBBEBEDC=<9742.-,+(&! AA +"'53267#?6632&&#"376632&&#"3##"'53267#%33"- dPY cP"9'" cP"9'"kki -O>3"- di -O v (+G))cO m ' )cO m ' p2R1 v (+2R1&ILu&IOu 6a@^,J_qK]rK_xK_ tL0.)(#! 66 +"'53267>323#3267#"&547#?&&#"#3"- Ln@:gK8%C(@N8JQ 468 .P v (+fER%$p  n 7GH"N742R1 S%KPX@ : DE,-JKPX@ : D E,-J@ : D E,-JYYKPX@% _qK _zK_ xLKPX@/ _qK _zK_zK_ xL@8 _qK _zK]rK_ xK_ xLYY@IG><761/*(#"! SS +"&'532654&'&&54632&5466323#3267#"&547#?&&#"&&#"5M"%N)#6 237nb CpB$O.+2 ''FH932&&#"3267 qq%MzT:])7%?$6L(40%E,+V~hAlBtEl=99{)7#& D0)V"& G6 3+))O&z)1"& F1 3+))& B&F '@$]IK]JL ! +332#'326654&##{pRm$4N+4.%FrnoV{:gD57 &H 7@4e]IK]JL ! +37#73732#'326654&##3#1770pRm$4N+4.%NNzsooV{:gD77lzT"& G4 3+ &HF /@,e]IK]JL  +3!#3#3{`Fydyvz#& D  '& H 3+/"& G 3+#& F& A& Br 3+#& C& K 3+F& LF )@&e]IKJL  +3!#3#{^.Fyxz)>O >@;  Je_MK_NL    +"&54>32&&#"32677#73h~+XWkN8A%5K/21dB+ewtGg<*v.IS%:6du)>'& H3 3+)>"& F> 3+)#>O& -)>& BYF '@$fIKJL  +33373#7#{..{34FF;@8  f  eIK JL +3#73733733##7#37#ZHJHIZ34M ZAAAAZUl?Y"& F= 3+F "@ JIKJL  +#77'7! NMC(QMCU] VV U#& D'& H 3+"& F 3+& A& B 3+#& CwKF&\& K 3+F& LK& J 3+uK*F(@%JcIL  +"&''326736-"'2 tx8[z*<KZ(uK"& F 3+fF%@" JIKJL +3366773#'{7!xR,,F5#fF& 3F@IK^JL +333{cF4z#& DF&%BN N3+#F& F&y 3+F *@' JIK^JL  +37'7373()'l7(c*b2.bNzF'@$ JIKJL +3333#667###{ }@ Ӌ 9F] (KU*F"F$@! JIKJL +333>773##{ 7| 6Fq78 ;E#& DZ"& G` 3+#F& TKF8@5 JcIKJL +"&''3267##3366735-#!8  3{ 8ziu$ 32'26654&#"tv'PyRpt&MxE,F(.+$;*|hDk@}eEl@{DqC17*GX.i(N#& D?(N'& H5 3+(N"& F@ 3+(N& A(N#& C("& EY 3+(N& KM 3+(Rb!*=@: )(J H_MK_NL#""*#*&*( +'7&54>327#"'7&#"266545h@..'PyRL5)>-)&MxQJ5,$;*_,F(".8;]Dk@2.79WEl@ *GXDqC (R#& D?(Z& JD 3+,#Q&@JKPX@#e _MK _ NLKPX@-e _MK ]IK _ NLK"PX@8e _MK ]IK ]JK _ NLK'PX@6e _MK]IK ]JK _ NL@3e _MK]IK]JK _ NLYYYY@!&&  +"&54>32!#3#3!'267&&#"ot%M{W+a( %F ".J+/{d@pEzb{v{}> GtE1/F +@(g]IKJL %! +332##32654&##{N`+w')B-5#F.N1gm?0' H /@,hgIKJL %! +3332##732654&##{ K]+$1-6#$HV.O2glp)+!(uNO 8@5J_MK_NL  &! +'#"&54>3226654&#"ZH ms'QzRnt'O"& G 3+#F& 7N$7@4J_MK_NL$$ +"''32654&'&&546632&&#"]> W(#')!+66`>bL2A$(42x%&!I75P.*q!%K2Wb#& D"& G 3+N&z"& F 3+#N&  KR$KPX@ J@ JYKPX@~_MK_NL@#~_MKJK_NLY@ $$ +"'532654&##57&&#"#6632pR86<,514 \ $+4 LS|tI^2i0?tv-'#)ZN/>eh2L)WL8dd?F!@]IKJL +3#7!#gaa||60F/@,e]IKJL +37#737#7!#3#g)`aii)u||u?"& G 3+1F&z2#F& 5QF$@!IK`NL  +"&&5467332673SF '@$JIKJL  +333667336673#'&7#X   w gF#JC6H X#AC%G#>S#& D>S"& F 3+>S& Ah>S#& CR]F &@# JIKJL  +#373#'2a9pB6A7F"@JIKJL +37373v1f-0dA7#&  DA7"&  F 3+A7&  AA7#&  CF %@"]IK]JL  +#7#7!3"*]oz_z#&  D"&  G 3+&  BU 3+H GL<)&f 3+IM @W_O    +7"&&546632*2A71=O/$C+83=Q- oK PX@ofrLK PX@frL@U^NYY@  +73!73#'!-FS:SFS:GWWWWE )@&e]oKpL  +3#737#7!<&~}6Sk 0@-g]oKpL    %! +!7#"&&5463337#"?6?Pd/ݘO,E>O.6Y46{B5/+s0 ʰ3+ "@ J]pL  +#77'7![J<]LV((VV([(V-*@'(JoKpL-- +#33667336673#&67##4467#<M   $ī   #}.Z$'Yp6=)_"6+4"(I!o6=)_"A@>Jf#K$K_'L +"&'53267333##&$ '# ;;AB6R{<@64Xd)0#O@L Je  Q ]#K ] $L +367!333###3#7!3#`F?M@v==G䐥JB'[G--cb?MNnN_7NC0%-=@:(J R]#K^$L'&#" +3667&&5473667!3#7!6677#37`Fq&,875"C D}[G--.#B+X,$U,N<E<   Ib8 2uَ 60KPX@ J@ JYKPX@Q]#K_+L@!Q]#K$K_+LY@+"&'532667667!3#7##($ (&E,~fF-g}('!CR |77DLLy+U]#,J#XK.PX@a]#K]$L@#pb]#K]$LY@ V"$!#+7663232654&##7!7!76#"&#"<08".!+F{@P\':d@)N!>q b}c$C0=O' ,J+rK.PX@' e a]#K ]$L@-p e  b]#K ]$LY@*%$!# +7663232654&##77#737!7!3#76#"&#"<08".!+F\b@P\':d@)N!>q b|}c|$C0=O' S-@*J#K`+L +"&5467'7!3267AMTJ<]V*#B 7G "(VV(l # n r 8@5J~f#K$L $ +376677#73733##7654#"'tkxy|}FJ%$\R@O- , <J~_*K` +L:81/*("  >> +"&&54>32&&#"32677332>54&#"'6632#"&'-Nj5)PyO3M60!$=-:3')) ,3K22#0#"S">^3.YU4X"R KN]~Gn 3Xt@KOA@ n?rL\P)"&?I$;@8  Jg_*K]$L$"&%%+3654&#"'663232#'326654##Gr$H(AO!~q'14=^5  n 2CjoYxx|2SR <@9g]#K] $L    ! +3#7!32#!3%326654##|A:~qi"4=^&L~oYxx6|2S=@:f  g#K ] $L$! +333733#32###%326654##q~qlql "4=^&KKKHoYxx|2S>&KPX@!e_*K _+LKPX@%e#K_*K _+L@)e#K_*K$K _+LYY@!&&  +"&54>3233##'2>54&#"5z})U\z;A5Rr?)F3:44U36 yYN{64G?\$3)));=><98@5 Jf#K]$L+#33'.7!'<wGdZK 3<;==; F@C J~e]#K $L +#667'7!#'##7#7#!&&##"*{!TEmB >4`~t9j ')?4>GD CF\Rن/13 ?@<J f#K] $L  +3333!#3'.7!'>G?\RS $3));=><~]zK'PX@  J@  JYK'PX@]#K_+L@!]#K$K_+LY@%&+##"&'732673#7667#x # '[=*  ": o7f^f x.,6-Q:0 MK'PX@R#K^$L@a#K^$LY@ +333!FHa~}}&,IRL605@2 Q]#K]$L +367!#3#7!3#`F?M@nc[G--cb?MNn|0NCtKPX@ J@ JYKPX@]#K_+L@]#K$K_+LY@+"&'532667667!###($ (&E,~}('!CR |77D|LLy+U]#Z-@*J]#K$L+333!##>7###  }G F|R"MK)IV)<&2# #3+=*6I@F  g_*K _+L,+ 20+6,6&$* *  +"&54>32'26654&#"7"&546323"&54632F-]a,[W:`9=2,}[G--cb?MNjNC4,7@4J_*K_'L,,+"&'5326654&&'.546632&&#"Ae#c0/75%FzOCX"4$<'*5/0Aw(*'A(13$&O_0U6...W+59yXB^21'v*(") f%*.K-*@N_8'7kyZ+=@:)#Jh#K$L'%"!  ++ +%"&&5473326767332673##"&' ,Q375K% L $A /NCR#H@EJe]#K$K_'L## +"&'532677654&####7!#32+ .'..jF}n_` +j|@= #L~~XN9}mRZ5@2J]#K_+L +"&5467#7!#3267-ALSU*"B 7G "~~l # n %D@AJe#K^$K]'L %$ +"&5463!#"332654&#!333#l9;>.A@*:}}4bO2&.7C 9(#(L5#KC-:Z5@2Jc]#K$L +"&54667#7!##"3267V.3.G&n|[.2#   6,2F' ~~/!XgF3@0Jg]#K$L%#+!#"&&5477#7!#32673:(c3,Q3K,Q'DE: |  @@6f$9@6Jg_*K$L$$%%%#+36632&&#"6632#76654#"seP 7,'$$Y-,Q375K&G#D"cO }' TE:  @)J@G!Je #K^$K] 'L  )( +"&5463!!"3!2654&#!33333#59;>.9IA@*:r}}}}4aP2&.7C 9(#(LL5#KC-<&22<$)8@5' Jf*K+L&%"! +"&54>32374&'3467#%#66E-]b,[k".I $#"h%!%i=p&2O {TQyWOV$2G4D]W"A@>Jf%K$K_'L +"'532673373#7#,3"- |-,t/= -O v (+G2R1<""O@L Jf  Q ]%K ] $L +3667!37373##7#3#7!3#IA*>b%j--6רꇥ}91GA**E` C2Rz x2C[<U" (/=@:+J R]%K^$L*)&%  +3667.546773667!3#7!6677#37IBX  )$s" .?\GB**4P h;N6%3##  9BPj&Ht%$<Q,#KPX@JK"PX@J@JYYKPX@Q_,K_+LK"PX@!Q_,K$K_+L@"a_,K$K_+LYY@ ##+"'532667>323#7#&&#",*"0@bJ2ZXG@)R\(1%!,? y/N.EfB! \.ZC2XC&7] -8_@\$1J gg gW_O/."!53.8/8(&!-"-   +"&54>32#"&'6632"326654&"32654,|y9]X;C&UI%O#L0[Q-bF.I<"% : 4-*) =l@!5$C, 9~3 VA1V5,$  : 14);r" 8@5eU]M  +3#!#3667#3rUPS<54&#"H\,>xYGY*8uW*", @;eeU] M! +3#73733#32#'32654##V]~..@; JW_O"" +"&&5467373'26654&#"Gk:_XaF-1#Fk;(7-3%;!: ;g@Xb>3dQ1x/K*'=)F,94/""XK.PX@a]%K]$L@#pb]%K]$LY@ d"$!#+7663232654&##7#7!32#"&#"-*:##*&:njZfq ? ''sXXrbO=S]/"*rK.PX@' e a]%K ]$L@-p e  b]%K ]$LY@)#$!# +7663232654&##77#737#7!3#32#"&#"-*:##*&:tJVndK_jZfq ? ''sXairbyasO=S],&3@0#J_,K_+L! &&+"&5467>54#"'66323267YY\R-1)!C)2W-NXRW43!a.*L QDEZ#lBFDR&|/?""8@5J~f%K$L% +376677#73733##7654&#"kK ]] ]] 6<"Vrhn,b==b4V?k|"#vn:".6@3)J`+L$##.$. ""+"&&5467&&546736673'2654&'9K$EC03P Jf7-V6 & +D&?b82o;$&# A;\N1+M,6Y4f%'$5"+5,:R@O* ) 8J~_,K` +L64.,'%  :: +"&746632&&#"326773326654&#"'6632#"&'RfE{O+<.!%4(#')&8$8*4S1AxP8W'O e^yU o -FM43?j@+. j*XDsX0!.#Ge-#1G@DJg_,K_+L%$+)$1%1 ##+"&&5477654&#"'66326632'2654&#"`HU& %G)CP 4!VW2rL..!(", *H."6  n 1C 6U?0[:g/ ! %-"&| JKPX@"g]%K _ +L@&g]%K $K _+LY@ &&  +"&&54677#7!663273%2654#"aHS#*>03CV1itt`#,=$! *H- 1pNC3[: "],%:  ,  JK PX@)n  g]%K  _ +LKPX@(  g]%K  _ +L@,  g]%K $K  _+LYY@ &$, ,%# +333733#6632#"&&5477#%2654&#"f4!UX2raGV& *e\c.. )#+ ^^^qmU?0[:*H."6O]/ ! %,3,&sKPX@!f_,K _+L@)f%K_,K$K _+LY@!&&  +"&&54>32373#7#'26654&#"=_5$HmI_pW,t/KFpB)9'!2  3^AHc8rfCj>xBi;)7-HR%Z,"^JKPX@f%K $L@Ue%K $LY@ +33373#'##7#3'.'#u1[py,qh"4*(.1*"7@4 Jf%K]$L+#33'.5#3'<B[hM;"4*(.1*llR"!F@C J~e]%K $L  +#7>7'7!#'##7'7#3&&##2Z-5%`  .#|PgK0[W$.&,-733O?eeegLq " hJKPX@f%K] $L@"Ue%K] $LY@  +33373!7#3'.'#3'#u1[yt,]h"4*(.1*l"9@6  J]%K_$K'L%&+##"&'732673#7667#xv  G8 '  ֒D h5DHu}ޖ< <q" )@&R%K^$L +3333!IAH]\\te*2O<"5@2 Q]%K]$L +3667!#3#7!3#IA*>b%EGA**E` C2Rzq2C[,,"KPX@JKPX@J@JYYKPX@_,K_+LKPX@#_,K_,K_+L@%_,K]%K$K_+LYY@ ""+"'532667>32!##&&#",*"0@bJ4Z\(1%!,? y/N.EfB!yW.ZC2XC&"-@*J]%K$L+333!##667###s[<ύ 5"}yW&Fo)@ ,,+>@;g_,K_+L! '% +!+  +"&&54>32'26654&#"7"&54632=_5$HmI_p"Gm81<)2%6"4=$($&& 3^AHc8rfE~b9rDh8-@+CL!A5b!*,!'00k,'3I@F  g_,K _+L)(/-(3)3#!'' +"&546632'2654&#"7"&546323"&546320~VYQo:'Nv=NUoI=r[6zoX5GfSAIe)(())((),,' ]j ]<Q9@6 Q]%K]$L +36677333#7!3#IA*7[$3)]GA**E` C2JnL2C[,(7@4J_,K_'L((+"&'532654&'&&546632&&#"r+NL'87%..=jB7Q%0A00(&8?!*!Q(#0j=8Y3-6רꇥ}92 y)9g$k;1* $RdMJ"04@1 J]%K^$L00&&%' +!7667##"&'##"&546773326773326773C C*+D !P14J ,6.7 t-(11)9FH@v" Q" ec>"5;@ JKPX@7 Wg   U ]%K  ] $K_'LK)PX@8 gg   U ]%K  ] $K_'L@5 gg   Uc ]%K  ] $ LYY@98765543$!#%+"+3>7!36632#"&'532654##732654&#"1!3#IA+)I<e]=5:K3&&W\#<9" /66&''3A*E\E27QL&.&& !4> L $A !2CZG"(L@IJg]%K$K_'L (( +"'5326776654&#"##7!#66323"%%$5%'\ L1IE & .O v-' qq!HC$-4R0H*"5@2J]%K_+L +"&547#7!#3267,@N88%C 7Gpp  n _"$D@AJe%K^$K]'L $# +&54633#"332654&#!333#~?=@4;>)7t\\`%1ZF2&.7C :.'"O%(C G=(:)"5@2Jc]%K$L +"&54667#7!##"3267V.30J'N\\.2#   6,4F'oqqO/!XG"3@0Jh]%K$L'$+7!#326773#7667##"&54677GD>N t V8JRqq#>ec>ޔ-+WF9#&^@JKPX@g_%K$L@gg$LY@&&$)$#+36632&&#"36632#654#"|cP1"  " I1FG ;=4!7' *KcO t' *?%.UH$4!#<9`:j")J@G!Je %K^$K] 'L  )( +"&5463!#"3!2654&#!33333#0?=@4;>)7t\\\\d1ZF1&.7C :.'"OO,8& G>',s,&RRV,,"'3@0Jf,K+L'& +"&&54>3237354&'7#667#=_5$HmI_p"Gm};)78y* = 3^AHc8rfE~b9Pj 9%. h < 9) [(%@"#H_+L((+"&5467&&54>7'26654&'bsoW4D|a >:4FGF%3'8D& hWg~91=H%|  )'"dJR|Dx.F&,4^>(.&'L A,&6KPX@J@JYKPX@"_,K_+K_'L@&%K_,K_+K_'LY@('0.'6(6"!&& +"&'532677>1##"&&54>323732>54&#"=P%&U/3@ D3'C)$B\85=qwKk/!$/#%/2%"1*WECk@+%FVc*]/JT%'/+FV+++6K&XLj4x& 4x"*lKPX' J' JYKPX@%K`+L@%K$K`+LY@%# ** +"&547332667733266773#7##"&'#DD AC0"5' /C0"5' 0to U98= W UH$47#<8_;#<9`:e1>;41>O// +j/ +4j/ +j/ +j/ +j/ +aj +~j<3+3+3+ 3+ 3+3+3+X: aRgG5)&f 3+VgG5)&f 3+BK2PX@f5K6L@f5LY@ +333#;A~K QK2PX@~]5K6L@~]5LY@ +3##!#7#|T%}@5@}%R|L.Ұh@ J IK2PX@5K6K`:L@~5K`:LY@ +"&'73267#3773XkaDBb g=5KLʰގ W" { <1!"f>nDc.Q-"BK2PX@f8K6L@f8LY@ +333#u-0"oK QK2PX@~]7K6L@~]7LY@ +3##!#7#H"~<%<~"N">JK2PX@8K6L@]8LY@ +333#7667t- 't. "+S*|*R)HY0=@:Jgg_+L(&" 00 +"&546776632'2654&##732654&#"(vj2xrdmZR;H8hR767-4>$#53& mc: hg[PV` SC#UN2wO80*vA>!%2E2-,=zMF@C.J" HW_ODC<:MM+".5467>7>70327#"&&'0'0>54&&5461"32>18r_9=;+?&&*B2.\NbHmh@R*"JCBHK PX@6n~||W`P@5~||W`PY@YWGE?=(& hh +"&'7326'.#0.#"1'0>3276654.54>1032667#".1>32)4#8=/7F  %./&&2&*?>*-/! =S32!  )20"*:> :E" |E^f(=7; "-" %KVZ*!E>1@5 '3F. ")& TRCz,04 !OR@O@?)(J~~|W_O#"31"O#O#+#&+'0>323266710#".#"".1'76632326654&&54>73+6 <<6)"  +/% *66$<)'#1h  %24 $30 * :6$.+@@+ !!-=+| "."3S/-]Q &*#* 3267>54.#"1'06654&'.54667>32>32326732661'0654&&#"06677"&&554&#" #!)) !49-("."  ! ,=&)I4 #1@)#& " 5Z2,! D 0%<89&"6 .*   ') ) _@9& J;: H    ~  |||||| W_ORPECB@642/('" __ +"&'46&#"'>3232>54&#"1'7>54&&#"#"&&57032632>324  ,70C)VF+ /72 )% '' $!K&/&0!10.0# 0>$$!!LG4q 2! ! &@KKEK A,:!  l  *2'A3%/3DUU!!$ -T@Q(J~g_qK_tL&$  -- +"'532654&##77#"&&546632&&#"33rM)a,GY8MC=Q(5^>)51 "/&.S]'<=*/d1S3If7 j;+"/^ \Nn,R@O'J~gg_tL%# ,, +"'532654&##77#"&&54632&&#"33oK(^+EW6KB7>7&&#"32>53#"&54>7663267#"&&54667032676654&&'#"&54632>54&'.9 1"$  +$>YK**8*4"6#=q[59'$#K@)9O04:':98[(C/'7R' %&,HR' -1 % 7  !1# 1<(![ '*!(7&  QX-SY2%-$ $5F*)(.Rm?0%PF+44+I:( !. B(/H4$9)'QE*$ ,<"%095$P8   :V23NcuA(@h>:~@{W >(=\ sJ  ~  gggg W _ O}|wuecQOEC:8/- +".5463232667'0>776670#"&54>54&#"'0>3232>7667>32032>73#"&5467667>54&#"9A1"$  1+8J=%?P1C) O?2:4 AL%0:< 1CKH -" %. %\db+"%4nW/- +0,!#/43!:+$mvcD (,$ (1-;B(|E"3k]9 @MICG$PBSS@PH/J~ggW_O75('&% BB+".5463232667.54667663>54&1707>79A1"$  /)*E=68;oA73A00 !@) !A5`|CPa=:=pX3& '6/ (7'  5];32&#">32326670#"&'67>54&#"267&&#"";%=%&T)  BR+4[u@---):cI( 27=DLT-+&/UqCG(!<!HA%6D(&E +WBB<?,%<20x,9$J(4$3 %# H+  *;>5`K+  .Nb5,8 <}qZ4*$gl\3CY&D-!11!B5We0Dq"a 5@2eU]M  +3!##'3#3#aGxCCCC6k5`` m~@{z ~{xM = J  ~  gg  g g  WW_ Ovtkiba][QOCA;:42,* +"&&54>54&'"#"&54632>54'#".546332667667>7&&#"32>53#"&54>766326732>7%!   .0"01<(![T9A1"$  -$>PA* W>4"7"=q[;@-$#K@)9O04:-A?8[(C98om !# #3> #EF=  .C-^ NcuA(@h>&5. (7&  C}XCL%-$ ,AN*)(.Rm?0%PF+44+QE1 !. O(@h+"JD() 5=,)6 ʰ3+82F >@;  JgW_O +"&&546632&#"3267'~pIOo0]0PU+K>W)X*/VS) Zpl] 8" ; zSO|a ?@< eeU] M  +3333##'3#3#axCCCC:6[5``a &@# Jt +333#%5aL5M:"65bca\ ?@<JeeU]M %!+3!2##'3#3#6654'axBl=cxCCx$/Sm[>_65`1@32#"&5467232654&&#"#"&'32>54&#"&&5466320654&'&"=Y0EqC :b@0<" 0%"$#-"1!./K+5#9#A3&% (M?&$<$%?(%# (EX{% '4\;=hE ;-)O3.29))< ,73,36aC   6NZ//36H(%'6Z4$(B(#--O:!  h8@10d vV |YL JhI  ~  ~g g  g g  W _  O:9rpRPJICA9:(& 88+".54>3232670#".#"32>54&'7".5463326677'0>7>77667>320>7"!':\S3@.."%#  /&DCF(6mY6 2,#3Jk.;!1"$  -',F= 8R,E07QB %&  G N `5%$ !RSF+ %!.Oe6&% #7A< ')+#(7&  6^;A1 ":e_/ $Ze5$ 8"'!** UL@@=lHG+ JvHW`PigOMDB+"&5463232>7>70>7667>1326670#"&54>7>10#"&&70>7>7>H3(!%+ )%7_VW/?|i# %"9?>,="5U2062(* 8> (/0"(&,' 282 0Si9=Y#3D?1/$!SYP(QWg J:*;#  "=e~@Vj -HTM8 8NUPUfd'L#JUI^ E5Qg1+1C/74&)>D@AJe]oK_tL  +"&'53267#73!#3#- "HWWA'I-F rV|5||BM!7KPX@J@JYKPX@!g_wK _xL@)goK_wKpK _xLY@20/-)'77 +"&&546675&&54>32373#'#'26776654&#"33#"Bj?6a>9=.JV'Ta"|$Z'^kFJ:A=P 4`>? *R=@Q, I87M04,V6V,4~p+=A,((-v10-&/?@<Jg_wK_xL*('%!// +"&546675&&54>32'26654&#"33#" r6a>9=.L^1o;,`b?pFFL8C=P 4`>@ ]\@Q, I88M0IXPM~DmRT,((-v10.&>.|KPX@ +J@ +JYKPX@goK`xL@goKpK`xLY@*)('$".. +"&&546675.54677333#"32673#'#=b:9b@5>MT 6b@=&ZlL|e (R?=Q/ *;!*iz2-v22,"pf6V,4 #+K@H% JegWe_O   +"&54>323#773#2>54&&#"@Q"Bc@4D B'RCB/Qbo2 ;&KUyL.; ""(/5@2*(JgW_O  +"&54>3232676677&"#"6654'nq*SxNH`'.-^-,YI4% +{$)/L9A m]@}g><>Bd ?4 -'lo)H'< V M@Jg geU] M     +"&54632'2654#"3'3#"-2/L; qrnC\CP&%*7>323266730'>54#"&1 ,+CX3%! :fO NR#2@H#;L+0+" ),$5 # .3%! ::29++L/%77%<@4 /FF/(?S@P ,J~|gW_O*);931)?*?! ((+".5467'0>7>32>73'267&&546326654&#"%0 ,*>K(+.4!/0*@*<)"  +M7( ),$5 # .3%,TZ%.&'1' 1o+%^jM[{Q4GVg@d"% MJ~~g g W _OIH65HVIV?=5G6G*)$# 44 +"&&54>17#"&&5467'667663273>73026676654#"26677 !*2OXO2" 6$$&  A #;#^:)'.v'B. 3T6N2GXx!B: "01-#"51O/BF=&{",B>7*G )87@ &D"(;!(@:5 ?I1GH17T,"J (+EPN; -N2(3<@ , ,)L@I%J~_zKxK_tL#! )) +"&'532677.54>32&&#"3267+ ) 7X4&JlE1M"-3 /A",(%D", 2Tw&7*XFIf:p El9//1T4)-F@CJ~qK_zKpK_tL--$%#) +331366323#"&'532677#654#" J1FG *3%R@  OC5"5' 060%.UH$4ɮWPl!@?#<9`: N'7KPX@%&J@%&JYKPX@#cqK_zK_xL@'cqK_zKpK_xLY@41,*$" '' +"&&54>77312#"'##327326654&#"4X6)UZ/+^s3'CX0c&qS:J#0 (0"!6 64  -bMTa=iCEx\4PF!jD@3wo&*=_47@1*]@ZJ  e_qK]rK_ tL&%$#"!  ** +"'53267#737#?6632&&#"3#3#3"- ;OOPY cP"9'"kkkk@ -O v (+b^G))cO m ' p]b2R1Y,0KPX@J@JYKPX@!g_zK _xL@)grK_zKpK _xLY@-+*(%#00  +"&54675&&546632373#7#'2676654&#"33#"_`XH!0=]//@&qtn:IAL/-$6` :H S=FE  5'KPX@  *$JK'PX@  *$J@  *$ JYYKPX@'  f _zK _ xLK'PX@+  frK _zK _ xL@6  frK _zK_ xK _ xLYY@)87/.;:7>8>21.6/6(&  -- +"&547#73>32366733#3267#"&'#"3654&267#AT-(Da:58|1JJ  *.> EF$8`(5 `fYEi:0$, vCY> t &+ 1A0 '/G7],>,,<I|KPX@ )&JKPX@ )& JKPX@ )& J@  )& JYYYKPX@&  h _zK _ xLKPX@2  h _zK _ xK _ xLKPX@9  hrK _zK _ xKpK _ xL@C  hrK_zK _zK _ xKpK _ xLYYY@'>=.-DB=I>I64-<.<('$" ,, +"&54>323736632&&#"32#"&'#7#7267654&#"2654&##CT$C\72<\ M#/T)E+tvz;a92D\F+? "."$k#9;, eaHh<)'F,otUE=R*.G$-wX>..'/+FV+/' " & 3>:&@"JGt* +'7.55467733267'7654''$E-` #,' dF %E< r $ kJm , )I@FJg e _zK_xL(&#! %"$$ +'73>32##!!3267#"&'732654#"$*MnG[\Q /%+F0+Y:Wt XC.#G@Av\5TAIJ @!oVX !(:,5?b@_(34 Jgg g _zK_xL=;8620,*$" 55 +7"&&546632>32##3267#"&547&&#"32732654#"o6##K;.MrK\[3.+F0+X;`x#& UK36*/<2)J.?f;TAVh ,4oij_  5#."<IA,0?JKPX@  B.J+G@  B.J+GYKPX@) gg_zK _ tL@- ggrK_zK _ tLY@!A@21FD@JAJ:81?2?#"00 +"&546326677667##"&&54>32373&&'2>54&#"27&&#"OOSI3J K3(B)&DZ35=ql '" L!TC/$$;#%D6& 2!>7:H!$ ("4*WE V9DD  ! TC:A.K,0"5( /C0"5' 0 # "e1>;41>UH$4H JYP932> I#<8_;?#<9`:Q " S,(2@ JKPX@!~_rK_xL@)~rK_zKpK_xLY@*).-)2*2((*.$ +3336632&&'#"&546677654#"72677"tp  S9FG ! ! SD:A-K,5"5' 0 $ "e1>UH$4H JYP932> I#<9`:Q " ),)4u@0&)JKPX@#g_rKpK_tL@'grK_zKpK_tLY@ #-$%$# +&'#"&54632654#"#336632%3267&#" 4M=DFFC5"5' 0tp  S9FG C    5>45P A#<9`:"e1>UH$47*;g, ,)G@J'&% HKPX@ pL@ tY@)) +.'566554&'%726654&'&&'1K,   &2N)!&  -,+ %)m, #B(+OR._ :%.J$,"+6K@"J43+%$# HKPX@ pL@ tY@ -,,6-6 +'7&'566554&'%7#&&'7&&'&&'26654&'V%%   <%H&2N)/#6_ / t)*.9%)m \n#B(+OR. $ :%,*;")A@>(' "JH_zK_xL$##)$)*%, +'7&577&#"766327#"'72667f<*$J$$7(?.";$##GmI<1y'9%35.e9 ,F,$3@KPX@ "JKPX@ "J@ "JYYKPX@$  g_zK  _ xLKPX@/  g_zK _ xK _ xL@9  g_zK_zK _ xK _ xLYY@#54&%;94@5@-+%3&3  $$ +"&54>326632&&#"32#"&''26654&#"2654&##Yn"FjH4M$^E3U)E+tvz;`7;\R('6!% .$t#9;, pdHb8(&$*otUE=R*#$!&xBi;)7,GR%,0" & 3>FS09CMKPX@&%#70J$HKPX@&%#70 J$H@&%#70 J$HYYKPX@"g _zK _xLKPX@,g _zK_xK _xL@6g_zK _zK_xK _xLYY@21KIFD@>1929+$%%$& +'7&'#"&546336454&#"5663266327#"'"7&4'32>#"3266E#`@\[3.+F0+X;5[R<"C""FjH)"'6= .UK36*((2 $*TAVh ,4o#$!&/+*T7Hb8 Bi;\ ,GRM5#."<F,'09C KPX@% JKPX@%  J@%  JYYKPX@%   g _ zK _xLKPX@/   g _ zK_xK _xL@:   g_ zK _ zK_xK _xLYY@#)(A?<:8753,+(0)0#! '' +2#"&'#"&546336454&#"5663266"3454&3267#'#"3266Yn"FjH4M#`@\[3.+F0+X;5[R(%4$!%)5UK36*,pdHb8(&$*TAVh ,4o#$!&x<.,0)7H1 5#."<,t,.<C@@ ,J_zK _xL0/75/<0<+)#! .. +"&&54>32&&#"3267&54>32#"'%26654&#"6W4&JlE,? "5%* @$HmI_p"GmJp9&[6(:'!2  .ZAIf:m(BP(51 Hc8rfE~b9N$*xBi;)7-HR%Z,tG7@IV@S'&$ H85320J%H1G_zK _xLBAAIBI=;/-#! 77 +"&&54>32&&#"3267&54>327#"''7&'77&#"26654'6W4&JlE,? "5%* @$HmI-&@9"GmJ0(D&[ !2 I(: .ZAIf:m(BP(51 Hc8 (.$:gE~b9++, $*-HRBi; "'@$J]rKpL% +3766773#7654&#"kK+,6<"VrhnV?k|"#vn0"'1I@F$%Jg]rKpK_tL1/*(#! '' +"&546776654&###32327326654&##GL -7-+tVgL6& (4N1 &%O@> +6/.="LGJQ;8$43 # q# r' #@ JHrKpL  +333667tp @'+A4"e)7 TG,KPX@ J HK'PX@  J@  JYYKPX@_rKpLK'PX@rK_zKpL@~rK_zKpLYY@$%$$ +33366326632&&#"&&#"tp "V1$ %]. "& @ 614"e5:b/8  HA,",KPX@  JH@  JYKPX@ ~_rK_xL@$~rK_zK_xLY@$#('#,$, "" +"&54667336632&&#"&&''2677"g:A-K,@p !T5  7V ! TT # 932> ,e4;WV JYP[ " ,/9KPX@ )%-*JHK'PX@ )%-*J@ )%-*JYYKPX@"~_rK _xLK'PX@&~rK_zK _xL@-~~rK_zK _xLYY@10540919"  // +"&546673366326632&&#"&&#"&&''2677"g:A-K,@p "V1$ %]. "& @ 51! ! TT # 932> ,e5:b/8  HB JYP[ " I,F@ J HK PX@_rKpL@gpLY@ %A +3"#"&'7327Y -S()T,WUv q IV,*r@ J HK PX@g_rK_xL@gg_xLY@#!**  +"&5477"#"&'7327632'2654&#"]V & -S()T,WU1#HM*Z:%  \D"6 q  W?2Y8h0!%7@4J_qK_xL  +"&'532676632&&#"*"[UN(  Y\ rOZ r[aR6""mKPXJJYKPX@rK_xK`xL@rK]pK`xLY@  +"&546733266773#7#GD>C5!6( Kp  R UH9'#<9`:"e1>Y"!KPX J JYKPX@%p  frK _ xLK+PX@)p  frKpK _ xL@*~  frKpK _ xLYY@   +"&5467#73733733##7#'3267#GD??..==0p  R25#9 UH)dde1> V!*,!'0YUH$47#<8_;v#<9`:e1>;41>S, " "3+&X,(KPX@%J@%JYKPX@~zK`xL@#~zKrKpK`xLY@$#"! (( +"&54677654#"566323266773#7#FE  53A 5"5' 0tp S UH9 e 98+8u#<9`:e1>g,g,".KPX@!J@!JYKPX@#_zK`xK _tLK)PX@+rK_zK`xKtK _tLK2PX@)hrK_zKtK _tL@&h crK_zKtLYYY@$#*(#.$.""%$$$ +'&&#"'6632736632#"&''%2654&#"84=> 4"DI(Q@QU "#% t EOY}RC$H. 5L, K6+N0_*)3HD" *@' JrKpKtL  +373#'wt>qr:  HX""G@DJhrK_xKtL""%$ +3736632#"&''2654&#"wt>q4#>C$H68V    K6+N07JE*)32D"d@  JKPX@prKpK]tL@~rKpK]tLY@ +733267373#'#,F  t>qr:1B2( P $:"""*C@@J~rK`xK_tL&%!** +"&'532677>1##"&546733266773=P%&U/3@ G6GD>C5!6( NKk/2%"1UH9'#<9`:"Vc*,A,DXhFK)&f 3+hFN)&f 3+hFO)&f 3+FP)&f 3+3FQ̠)&f 3+2FS̠)&f 3+ FV)&f 3+-FW̠)&f 3+VmG`5)&f 3+F+G5)&f 3+RbmG5)&f 3+AG<5)&f 3+>G 5)&f 3+5]G55)&f 3+NmG 5)&f 3+"| @_wL +76654&&54663"% NF*N}T"&:&R5"<&:8- $2:@6! '7!MK,PX@_,K_+L@g_+LY@!! +"&&54>32'2>54&#"Mg4.Rk<>V6GS!3#+,#5#+ >jBL~\1(CR+eXx'@L&?9*CM":;- 9 JK,PX@ %K$L@ ]$LY@ +37667'%36 'SAzuR  5i7P@  JK,PX@_,K]$L@g]$LY@ '%(+#77>54&#"'66323;@$>.C2wLXUF(@A(LY7+u@$JK,PX@gc_,L@!ggW_OY@ +++"&'532654&##7326654&#"'66327b$(a-GY5IC$+P4&*,F>0kOccZT6L>:;$0l2*(!d ']FJg HD9gAX+ RJK"PX@%K^$L@f%LY@ +7!733#37>7#&}ZVV& *rYu,h@7 4N"!A@>Jgc]%L !!+"&'5326654&#"'!#6632:a$X083eq( 6X3?';&6 &f)TAJ{I+30G@D Jg_*K_+L! (& 0!0 +"&546676632&&#"36632'26654&#"hi&G11zR;3dtJ5IW7##"&54>3226676654&#"!@;!6L2 F2URN("+lR(aY:o}G/+2y.  )4/E#*,  :@7J_*K_+L   +"&54>32"7&2>7e`(PvM[h$Kw/$0% |rbQny_Ue2Q`/G2Tg5)*7 K- -7 Y7 X+ N" '/  X6"  X7 \:` `3+6{` `3+Qt` `3+Xu` `3+W'` `3+^(` `3+`;` `3+ {)` `3+X*` `3+Y<` `3+?:~ ~3+Go{~ ~3+t~ ~3+/u~ ~3+'~ ~3+7(~ ~3+D;~ ~3+M)~ ~3+3*~ ~3+A<~ ~3+G& q?d& '  GV& 'q ~& '  /j& '  & ' *GD& 'q 7N& ' G& 'q  G[& 'q G& 'q'  1sD3: ް3+}&){ ް3+}?3t ް3+u32u ް3+}<,' ް3+uC)( ް3+uK2; ް3+}a)) ް3+s=3* ް3+u@2< ް3+~>' d'  dd3+d3+4)8" %@"a]rL    +%"&&5463!'3# Ba5vf(VV)/n`v]?J)N" $@!a]rL ! +7!2#'3#J(fv5aCVV)v`n/]?b ,@)ea]oL  +3#3#3i<8710/-)'#"! 66! +"&547535!5!"&547!5!&54632!!'3654&#"2654'#5!5!535654&&5432  s8j$7$$E$/* ! + ¶8. #P# f------$ - %% - $ q  T------# '#P  &"44 #/;K#PX@&    g _wK _xLK,PX@$ g    g _xL@) g    g  W _ OYY@+10%$ 750;1;+)$/%/##     +"&54632"&54632!"&54632!"&54632"&54632%00%#//%00%#//%00%#// %00%#//%00%#//D&)+%%+)&&)+%%+)&&)+%%+)&&)+%%+)&&*+%%+*&4 #/;K,PX@& g  _wK _ xL@# g  c  _wLY@+10%$ 750;1;+)$/%/##     +"&54632!"&54632"&54632"&54632!"&54632%00%#// %00%#//%00%#//%00%#//%00%#//>&)+%%+)&&)+%%+)&&)+%%+)&&*+%%+*&&*+%%+*&\@ JK,PX@e]pL@Ue]MY@  +'5'7#53'75373#'I_hBhhCh_iBhhCh hCh_iBhhBi_hBh@GU]M +'7#5!!" 8@@4 #/uKPX@#  g_qK_ xL@!g  g_ xLY@#%$ +)$/%/##    +"&54632"&54632!"&54632"&54632c$11$#//$11$#//$11$#//$11$#//h&*,%%,*&&*,%%,*&&*,%%,*&&+,$$,+&4 #/tK,PX@#  g_wK_ xL@   g c_wLY@#%$ +)$/%/##    +"&54632"&54632!"&54632"&54632%00%#//%00%#//%00%#//%00%#//>&)+%%+)&&)+%%+)&&)+%%+)&&*+%%+*&J^y 3+)C@U]M +773vvd GK"PX@g_tL@gW_OY@  +52654#52d 81<<2738227  Ȱ3+ m 3+w}2@/HW_O  +77"&54632w'4&)+%%+)&&*+%%+*&&*+%%+*&H]KPX@8t^]PBA4 3  J$ IGKPX@8t^]PBA4 3  J$ IGK"PX@8t^]P BA4 3  J$ IGK.PX@8t^] P BA4 3  J$ IG@8t^] P BA4 3  J$ IGYYYYK PX@Q ~  ~   ||||| czKrLK PX@Q ~   ~  ||||| czKrLKPX@Q ~   ~  ||||| czKrLKPX@U ~   ~  ||||| czKrLKPX@Y ~   ~  ||||| czKzKrLKPX@_   ~  |   ~  ||||| czKzKrLKPX@e   ~  |  |   ~  |||||czKzKrLK"PX@e   ~  |  |   ~  |||||czKrLK)PX@q  ~  |  |  |  ~  |  |||||czKrLK.PX@s  ~  |  |  |  |  ~  |  |||||czL@y  ~  |  |  |  |  ~  |  ||||||czLYYYYYYYYYY@ ɼ&(,,,-. +70&&'667.546327.54632661.763270&&5463270&&5463270&&5463270&&5463210663266322663212663212663212663212>3216632&30                &  %&#) %$' ++ -, +,'( %/"60 )&/ ">:  5/!)%     )%  / &0  "+ 1!     %      #  $       &f@U]M +5!@@M'""M&"3++(3+#4@1]oK_zL    +#5!#7"&54632ֳoGG#!@]oL +#5!#ֳoGG<O$@!a]oL +!%35#<{O{G", #/;@ JKPX@#  g_wK_ xL@   g c_wLY@#10%$750;1;+)$/%/##  +"&54632'7%"&54632!"&54632"&54632"**"!**JIIJ -- ,,S -- ,,"**"!**J$%&$$&%$IJJI!''""''!!''""''!#&&$$&&#@GU]M +%!5!#@@hkGx@P+?@<J~_wK_xL! '% +!+%- +76676&&'&&546632&&#""&54632"$a'K#D#(0% o*"-7!(5"B+=a9"m+')&D2$+$=%")6#+ 0@-Ja_zL      +"&54632&&'73*"-7!(5  +$=%")67~5 4;x|WK)PX@]oK_zL@g]oLY@  +!#7"&54632xGx|@]oL +!#xKw}2@/HW_O  +'7'"&546326' m>+,>>4Y66Y44Y66Y4Z>,+>>+,>4 #/hK,PX@ _wK_  xL@  c _wLY@#%$ +)$/%/##    +"&54632!"&54632"&54632!"&54632%00%#//%00%#//#%00%#//%00%#//>&)+%%+)&&)+%%+)&&*+%%+*&&*+%%+*&7K"PX@Wg_OK'PX@"~Wg_O@)~~Wg_OYY@###" +7663232673#".#"7}\7{03> Q&)+%%+)&&)+%%+)&&*+%%+*&5 p #I@FJGgWg_O"    +"&54632&&#"56323267#"&"%%&&&%3<2K;/%4=2K;#&( (&# "q5  "q5 5P#E@BJHggW_O##$$$" +&&#"56323267#"&"&54632%3<2K;/%4=2K;(%%''- "q5  "q5 #&( !'%$5 &aO'n n3++"@]rKpL +!!5!kI+6@3&Jc_qL!  +!+  +%"&&5467&&546632&&#"'2654&'5U26-6_=1Q&(D+'(*vhS%-)#%B-1F22E$^ 4^V]`$+ ,-: #fK2PX@ g_qK_xL@gc_qLY@ ##    +"&54632"&54632"&54632#33##22"#33#"33$#33#"33O'+.%%.+''+.%%.+'',.%%.,'t 3+( " 3+ O 3+!6&   3+ '"4 -@*_wK_xL      +"&54632"&54632$11$#//#$11$#//;&*,%%,*&&+,$$,+&4 #ZK,PX@_wK_xL@c_wLY@ ##    +"&54632!"&54632"&54632%00%#//%00%#//%00%#//>&)+%%+)&&)+%%+)&&*+%%+*& !@ H_tL   +"&'73267`s-bBB~2"2`\PEEP^^+e00+7+Pw: 0+'7'77'%A-3,G$F)2)4:?+??3?;+:: #/;GAK PX@? g g _wK_rK _xK _ t LK#PX@= g g  g _wK_rK _ t LK)PX@: g g  g  c _wK_rL@8 g g g  g  c_rLYYY@3=<10%$ CAXI@&JtII%$ +56654.54>54.54>54.5467>@D''''''''''xc?D(''((''(('xP--&'.-''..&ORQ,-&'//'%,/%OR1$9BI@ GF@ ) (!J< I  ~  h g ]qK _oK ]qL;:&%?=:B;A4321-+%9&9$$! +&&54667533253&'67##2675'"&54675"327&5xBuMP+*P%F ,3,C9=#P)- Lx/7r0lq]OvC )( *(%- RsC ;58A p   ? \h`m8eHnz&4? Dt@U]M +&&'73g/ 7~5 4;C AdD@6 JHeU]M+D'#7'373#73'7#'#3DEEDCFFC-c22c--d22duxyuuyx,NVWNNWVn60+7'&&'6'6&'*%H(.G::$/ * .$::H/(H%Iy 7Y Y Y3+5W X X3+Pb; $@!U^N +33P_Tb $@!U^N +533^TjBP ;@]oL +3#P T @]oL +#53 jTB$b'  b&  +@(eU]M  +%".54>3!!"3!4hT32Ug5/XE))EX/B<54.#!5!2#/XE))EX/5gU23Th40/,,/0B<333FL ,3.  &KA # ;,F0< F n %b09k i-(G= k1H*:@7 Jgc_IL*)#"!  +'6677667'&54677654#7323"#/- <,F;OA&+23 'J=kj,)GD $k@.  F m!%b.:w]WFKPX@a]IL@eU]MY@  +3#3ZsYbbw7WFKPX@a]IL@eU]MY@  +73#737YtZҜbb H,@)]IK_NL  +73"&546325>h`) /0!%3~%&4!,,H'  w 0@-gU]M       +"&546323"%4)( .hz?5!+-%%5B~hW.KPX@ IL@ tY@  +&&54673]"ld|;]64Be?a<9W .KPX@ IL@ tY@  +6654&'38Yrp! ge^<97Be@P(?@< J~_MK_NL$"((%) +7>76654&#"'6632"&54632i ("( C%/'`3R_ 4 #Q)/0!%308'kH@+:)$&4 ,,qM 'D@A$%J~gW`P #! ' '   +"&54632"&54667>73327!%3)(!/R` 5"w (")5K/&`5 +-$%5BH!c"jK#PX@#]oK]rK] pL@!e]oK] pLY@""! ! +3332673#!32#6654&##q~Zz>M_|_FsW@EW* 3~821zXHX?Yv:8Z4,5"2*GP\kKPX@-.  WTJ FD J@ -.   WTJ FD JYKPX@*   W a_wK ^pL@1  ~ W a_wK ^pLY@"RQjha^Q\R\PNGGCBA?>=1/+)%%& +7&&5463236632366326654&'.546632&#"#7"'#7&''6654#""7665432776654&#"!$*3,/- #8-8$<64-:.:(& ,, +"''7677#"&54663232#"&'''3267376654&#"32654##77l>)a :H=3:<DRL8& J'R<:6"0G^r#A18J8BML<$M5>4PL[XAEA-& + "!1AO WA9/+|@"JK PX@'n~_oK] pL@&~_oK] pLY@++'"1 +#73&&546677323273&'#7&#"#733 5@CcC C&'%("C%$C8<-eU^~$sKOlmegp   {I2^=~= x ʰ3+#YX @ J Ht+&&'#467&&'7>737RkcLI)NF+bc,%(mM=0MI`pQ.CH%^i8+c`%aC:d).  ɰ3+ E+@(eU]M!#+35!54&##5323 *DO]l.MXSOV6u]X KPX@_wK`pLKPX@_wKpK`xL@"oK_wKpK`xLYY@      +"&546323"&54632Y$11$#//y(v$11$#//4&*,%%,*&6 &++%%++&E&@#U]M+!!5!#"MXX# ` `3+Uox(/@,eU]M +5!5!U##BBwCCaP@ HGt+5>554&''5#'2C'T3 ;f'%i,)4$}!]) J@s+ʮ00E ] ]3+Mp@]L+5!M#CCQ"XJKPX@rK`pKtL@rKpK`xKtLY@$% +33266773#7##"&'#!B#5% 0tn @'% !% :_7V.2 ; 8!1AQ_m{KPX@8   h g_wK _ pLKPX@<   h goK_wK _ pL@@   h goK_wKpK _ xLYY@Kona`SRCB32#"vtn{o{hf`mamZXR_S_KIBQCQ;92A3A+)"1#1!!  +"&54>3232>54#""&54>32!"&54>32!"&54>32%2>54#"!2>54#"!2>54#"DF/O:CI0Ps  FG1N8CI0N1FG1N8CI0N1FG1N8CI0N      RJ,eZ9NM+e[:6y'0* ʰ3+g/* ʰ3+<X ʰ3+;!;@8  JgW_O!! +%"&&54>327'2654&&#"bZH9cK!*rz0T5std=gZe5]Rŀ je7CeaXHJ'B@ 2 ?3 @ J~~   ~g  g g  W _ O)(=;750.(B)B#!'' +"&&54>32373#7#32>54&#""&546632&&#"32670(A-*KMH0`s! &5J*P:0 )4(1m:0!ME-,-6!24/F#6>:D=i? G +D$; K J'K@ < =+ * J~~   ~g  g g  W _ O)(A?:8.,(K)K#!'' +"&&54>32373#7#32>54&#""'532654&'&&54632&&#"0(A-*KMH0`s! &>(/2" "E=!;)(Qm:0!ME-,-6!24/F#6@L ( 58 A  ,":=G79K PX@  4JK PX@  4J@  4JYYK PX@=~ ~ ~g gW_ OK PX@6 ~ ~g gW_ O@=~ ~ ~g gW_ OYY@% 3210-+'&7 7 +"&546632&&#"32673"&546773326773#7#5J*P:0 )4(1s[,+']*!- \IF4k:D=i? G +D$; K 65- $&N7?''&r&g&H!K@H  JggU]M+35&&'66753&&'667!Q\`Mb;6*37/)%%nabkd_M  RUSC56C$& K PX@#     JK PX@#      J@#     JYYK PX@/  e  U  e ] MK PX@3   e  U  e ] M@/  e  U  e ] MYY@( +%3#7#!373#'!!#3#37667X9 };[0q9o"2(?X  6oX}~)J&#K'&r)M?LQ)8@5J~wK_xL%#))' +7'66327667>54&'"&546328 -2s4aZ>D*7  *"-7!(5W l"[G@V-0#+$=%")6.'6@  ! JKPX@7n   ~ f  g  W _ O@6   ~ f  g  W _ OY@)(0.(6)6''&%$#'&+3#73733733#36632#"&'###%2>54#"|DCy >2(F,"@\:4Aq|y|x-"@/!%I_PPPP_T!2&QAC~d;,$FIm%?K%V,CH'/6#R@OJ~eeW_O ## +"&'532654&##77#737#7!37a&@AKZ6HKqyS]M  <;)2d}h}`` \PPk6,vk}@8D? bR e J  ~  ~   ~  ~  ggg  h  gW_O~~|{us[YKIC@20-,*(#!kk+"&&5467&&5466776610&&#"327#"&54663232663206322&&546321#0>54'6654.#"227'"&#"767&&'72654&'"#"&',20H*A! !+   #(     " 2C+G2 $"e= 2 -$(% +b    yt$![040 )& $:!Y5)) )e  )  0/GU'BP(4$$%%2 7X!:$)A:%)> 2_ " 4+ V92U+4hJ@G  J~gW]M! +33273#'#7'#32654##k}+G+&C(+N:T&@G`$\h8Q9+8>>s89PVG@D~ ggU] M! +!##35332!6654&'c\a~7yd!\VT^n2QQiaoHl$T@Q #"JH~eU]M!+3327'7#'##337"0##4'6 EMZCIR?c(:T&-$'@14>Gd[QUkP* Eg$9K PX@40(JK PX@40(J@40(JYYK PX@gW]  MK PX@-~ ~gW_ O@gW]  MYY@%%%9%932,+*)'&$$ +"&'532654&'&&54632&&#"733#5467###!><)(8/9?;-6!/4%J}^^a[@e5`g = /'&9 5(.#41`+*!N\jxT@Q6*$ KE?J   gW_ OsqecWUNMIG$!'''''(!+53267.546323267.54323267.543233#"&'#"&'#"&'#7>54&#">54&#">54&#"">$BD% ?$"? "%?$"= " % <#7U !V67U !W66V !S4 !%% x $$ x %%  < "UY'so'VU# "UY''WU" #UX''WU" <sJN"POOP"NJJN"POOP"NJJN"POOP"NJjT@Q ee U ]  M +#5!#33#3#3333ve fņ||3?j*66`6Y4g6`6Znm.@+ JHt+73'736673#`5;j Қq+j@=V!G"6*P^T@QXIJH~ggW_ORQQ^R^DB97.,(&PP +"&&7667&&54>16676632#"&5463232>54.#"'2654&&'1Q."!&89&*2 (Y)R'?S)$FhES\*&*@(3B(.'.j40Z%50CH$7&62U62g0+\5:bK4'OaA46\#FBB?P @ J]$L+3773#5>BBzP @ J]$L+3753#>BB0P@"1%@"JH]$L+3'753,CĻ1P&#@ J]$L+!'773-BU/P"$@!JH]$L+!'73,nBƸ2P( LJKPX@]%K]$L@e]$LY@ +!#'73530Bɳ/P& %@"JH]$L +!5'73(kBsK4P&"@J]$L+!73.:B^.2P1%@"JH]$L+3573hBiSP '@$JH]$L +!753>B},WP -@*JHe]$L +!5#733;B7P '@$JH]$L +!773ԠBBPz  '@$JH]$L +!5'3>BrwP @ JH]$L+3'3#'X>ԠBBPN.@+J]$K]$L+3533#NBBBnP-N /@,J]$K]$L +35353#NBBBfPvN /@,J]$K]$L +35373#5NBBBPN /@,J]$K]$L +35353#NBBBqP1@J]$L+3'53#NנBBhPSi@J]$L+3'3#N<ܠBB xP %@"J]%K]$L+3'353##N;զBBwP @ J]$L+3'3#5P>BBPa- @ J]$L+3'3#'N<٣BB$P1"1@J]$L+3'73#5N,CC1P"@J]$L+3'73#N,éBBn2P&#@ J]$L+!''73-ȠB/UP& @J]$L+3'753#N(ȠBBk4KsP( *@'Je]$L +!5#'7330B/P&"@J]$L+!'3.hB2.^P1@J]$L+3'3#N8CC#i$P #@J]$L+3'3#]:kBB!P&@J]$L+3'3#N4ҢBB&i/P  @J]$L+3'753#P:˭BBy"]Py @ J]$L+3'3#5'N4ҢBB%iP' #@ Je]$L+3'33##_8BB#e(PF%1!@J]$L+3'73.CS3P'$@!Je$L+!#'73/n0P.&@#JH]$L+!'73'ɗB7q2*P% '@$JH]$L +!''753-ɠB2P% '@$JH]$L +!5'73)ɠBrx3sP% '@$JH]$L +!'73*ɠB93P1!@J]$L+373>CvGP@J]$L+373#=BBuCP%@"J^$L+3733>mBvnP @ J]$L+3753#=BBu9?P @ J]$L+3773#5>BBvzP @ J]$L+3753#>BBv!0P@N+@(J]%K]$L+!#5373}æBTnBPN+@(J]%K]$L+!#533vBBPN ,@)J]%K]$L +!5#533BOBPN ,@)J]%K]$L +!'#533B-B#P1"@J]$L+3573:CP#@ J]$L+!739B|#P!@J]$L+!'73:mBxcSP $@!J]$L +!7539B"@XP *@'Je]$L +!5#733:BP $@!J]$L +!773:B2P%1"@J]$L+3'73.C+1&P'#@ J]$L+!'73/B/0$P%!@J]$L+!'73-jB21 P% $@!J]$L +!'7753/B͠/P%"@J]$L+!573.;Bi1P" *@'Je]$L +!#'733Ȥ0BF-(P"1!@J]$L+3'3:P R>Cp'i ' " t/$0@-o# #3+mjfNj^:C^v^ZR!}^J ^/K^M#]EONJ]Q^L;6J&dD@U]M +D7!sgg"TT2dD@'U]M +D73!73e%d%$d%T;^ ;dD@0 JU]M    +D.'53!.'53.' .( ^47 "M% 47 "M% ^U GdD@<I~gW_O      +D"&54632"&5467332673T% !$.GTHX,6 I`"% (~J>S.%J[^.dD@#W_O!" +D6632#4#"c ]V;EUK&1^OV'=!="F4C ְ3+64Fv ְ3+V& ZdDKPX@noU^N@U^NY@  +D7#7373Jn mB)A@ ;_< ^P İ3+90SdDK PX@nU^N@U^NY@  +D73733 HAH B 87>B 0 ,[dD@P gg  h  W _  O"! (&!,",   +D"&54632663232673#"&&#""&54632w&!$>+3) 9"W1+ a&!$4"% (?A~"% (] \3WdD@Lg g W  g _   O331/+)'&$"$"$" +D663232673#"&'&&#"663232673#"&'&&#"B>+$  9@)'   V>+$   9@)&   7<  7<  7< 7<  %b 0dD@%JHGU]M +D'7377#i c j c\\>>\\>b%dD@Ht +D7#7#};pG;x__xe '/7?GKOW_gow$dDK PX@/-"&,-p6 e754 U  9 8  g;:g=<gA@g?>e!C B#g%#E$D"-#"g+)'H*G(F&,'&g20,..,U20,,.^K3J1I.,.NKPX@/-"&"-&~6 e754 U  9 8  g;:g=<gA@g?>e!C B#g%#E$D"-#"g+)'H*G(F&,'&g20,..,U20,,.^K3J1I.,.NKPX@6 e 754 e  9 8  g;:g=<gA@g?>e!C B#g%#E$D"+#"g)'G(F&*'&g/-+H*,+*g20,..,U20,,.^K3J1I.,.NKPX@54  ~6 e 7 g  9 8  g;:g=<gA@g?>e!C B#g%#E$D"+#"g)'G(F&*'&g/-+H*,+*g20,..,U20,,.^K3J1I.,.N@54  ~/-+&+-&~6 e 7 g  9 8  g;:g=<gA@g?>e!C B#g%#E$D"+#"g)'G(F&*'&g+H*,+*g20,..,U20,,.^K3J1I.,.NYYYY@ɤyxqpiha`YXQPLLHHA@9810)(!  }{xyuspwqwmkhoioec`gag][X_Y_USPWQWLOLONMHKHKJIEC@GAG=;8?9?530717-+(/)/%# '!'     L +D53#!5#53%53"5432"5432#"5432"5432!"5432"5432!"543253!53%"5432!"5432"5432!"5432"5432!"5432"5432#"5432"54325353!533353f_gLO;NQ6_5>y|b;g566fz.6ff6f66p.F3VF.p6gg666N0dD@% JU]M +D5667&&'53., 6886N3  2 D ~R9  3+^U BdD@7~gW_O   !" +D6632#4#""&54632X`OOJHX,6 ]% !$J[UPS-&R"% (e!# 0+''7'7731/12*31/1221/13*21/13p0dD@% JU]M +D.'5>73 6996 ., D 3  2(0dD@% JU]M +D5667&&'53|., 68863  2 D %dDKPX@ " J@ " JYKPX@U]M@~U]MY@%% +D5667&&'5375>73#&&'., 6886 D 3   3  2 D  @BB@ B@bW;  3+fNK"dD@  Gt +D'7'7'37'j83F> F >F38*0 B"FF"B 0*@o+VdD@KJg  W  _O! '% +!+  +D"&54632632#"''2654&#"32654&#"1<<1891<<187    8227''7228((2TZdDKPX@noU^N@U^NY@  +D7#733i{"3{"TCxCxJ@ 1dD@&W_O    +D"&'332673X\}m]4dFea,712h^K ; ;3+^&dD@U]M +D7!^ggSpi a 3+_4dD@)Wg_O#"#" +D66323273#".#""oB736886 .,N D 3  2x%dDKPX@ ! J@ ! JYKPX@U]M@~U]MY@%%  +D5667&&'537.'536673., 5995 3   3 3  2 D B@ B@ @B9^j'L>M>3+^@U]M+7!\^gg^\LG^Lwm<6 dD@  JKPX@"UWg_O@#Wge_OY@     +D"&543256673"&5432 E""! {=" E""H!'@ V !N'H!'m(6 }dDJKPX@"UWg_O@#Wge_OY@     +D"&5432&&'73"&5432 E""!s E""H!'@&O! $M" H!'^)dD@ Jt +D5>73#.'!TXP[c)a%[Z%II^ %)(53 'rH.0+'77'*r*rHOO=AOO=T0dD@%JHU]M +D'73B*xTMOA[ wdD@JHK PX@!pWg_O@"~Wg_OY@#+#" +D7363232654&'7#".#"OB#/*+1(I=*A4+",n@ 6&AK#$T0dD@%JHU]M +D537Dx*T[AOM ^k'L>M~>3+L&dD@JU]M +D'#53xLA[M""%dD@GW_O$% +D'6654#"76632>)*.%)3?K%;"2 V:45Z,'8dD@-J~W_O$. +D"546654&&546654#"'6632W !3     P6dD@+Wg_O  +D"&&547332>33#" :)[)6J3":77P5. _^&JJQ+]E #/UdD@Jg W  g _O%$ +)$/%/##    +D"&54632%"&54632!"&54632%2654&#"]6CC64HG#'#$$#'#$#]>66>>57>.%(#+%(#+pRNR",UdD@J+Jg  W  _O$#*(#,$,""  +D"&546326632#"&''27&&#"32654&#"7ED8C08%6E 7$%99&###%"RF;5JH(G9":#%"*D>#%##<;CT)dD@ Jt +D&'77366778 ! @+ L-C<55 52?m #DdD@9gW_O ##    +D"&54632"&546323"&54632#'#$$#'#$##'#$$%(#+%(#+%(#+  0+'7'77''7'77'%A-3,G$F)2)%A-3,G$F)2)4:?+??3?;+::4:?+??3?;+:?CdD@8 gW_ O??=;75$$"$$$$# +D>3232>3232>32#&&#"#".#"#".#"#F8$.-&&-.$5G%N*.%'/.'%. )8b=''''''''9b<0( dD@t   +D"&546773!!aTr)!,  *cC 2dD@'U]M  +D6654&'3!&&54673AAc"Q(' ((O! &%R$"N*' cC )7JdD@?U]   M***7*710))#"  +D6654&'3!&&546733&&5467336654&'3%A@B AAcS+' ((O! '(O""N*' &%R$"N*' "Q(' ((O!l N 3+hJG{l l3+hGEl l3+ G|l l3+hJG&l l3+ GI l l3+lG l l3+GJgRlG l3+3+ JGSl l3+ GMl l3+GFgXlG l3+3+l*FGZl l3+hGl l3+hGl l3+hGl l3+p  3+1E'.dD@#W_O#" +D6632#.#"E aWZKm9AmE]P"L?! !k/GdD@<$I HggWg_O$$$$$$$" +D76323267#"&'&&#"76323267#"&'&&#")4%#.)4%$.2(6%#-)4%".oN$ M$ N$ M$ hGl l3+hJGl l3+hJGl l3+hGl l3+h>JGl l3+hJGl l3+lFGl l3+hJGl l3+l FGl l3+lFGl l3+hJGl l3+lJGl l3+ JGl l3+hJGl l3+lJGl l3+lFGl l3+FGl l3+lFGl l3+h%FGl l3+"FGl l3+hJG`l l3+h'FCdD@8JeW_O +D"&54663!##7#"3267&5:* G)A)o#&#h%+&A'-:"%0hJGl l3+hJGl l3+lFG Ml l3+hG Nl l3+lG Gl l3+h JGl l3+l FG Tl l3+lFGTl l3+lFGXl l3+l"FGZl l3+M  3+B  3+ "W ð3+#BV ð3+NL1 3+rNL 3+sK Z 3+X'@%dDK"PX@gW_OK'PX@$Wgg_O@)ggWg_OYY@!  %% +D"&54&#"3"&546323265442@2@>52A2@?X:1#<=40@:0"<=30AO@dD@5JggW_O%$$$ +D72654&#"3267#"&546632 ;M!%5&@'ADILJ$G 52'<"R;klb0dD@%Ue]M +D7#733q63t6CxCxkcK 2dD@'U]M  +D76654&'3!&&54673 @h Ak O+( ((O! &%R$"N*'  +@(W_O      +"&54632#"&54632#'#$##'#$$&'#+&'#+8 @W_O   +"&54632 */*,+!*,!'0# %@" JU]M  +.'53n.( 56 "M% # @Jt  +56673< )21 U# ),) V# 1@.JU]M    +5>73!5>73P)) *43)) *43 37 ),) 37 ),) u#(@% JU]M +5>73#&&'u653a-7 47#T .' #)@& JU]M +&&'5366733a-7j64#T .' 47 ()@&W_O  +"&&547332673J:FUK&1\ ]'=!="OVj 1@.gW_O      +"&54632'2654&#"Z6CC64HH4>66>>57>E},@)Wg_O"""" +66323273#"&&#"}G3 .'TG4 -' OH4PG4@U]M +7!.ggPy~q" 3+]Q)  3+}m FT}[dDJK PX@pU_O@~U_OY@   +D"&547733267/**\  %* ?1 D|0dDKPX@noU^NKPX@nU^NKPX@noU^N@U^NYYY@ +D"&546336632##"  !0(,q]2dD@'Wg_O%$!+D732676632#6454&#"#q )B1/BY  [@^_ 6;   SdD@ Gt%+D&&5463254&'J FI)`PXDG/SA*,%*q&*N8.[A M9C<++9 *-9(hJGRl l3+0 HKPX@oU]M@U]MY@    +"&5463!#)#0(I^ FKPX@nU^N@U^NY@ "+536632#M !^I,BD/;fE/;E/;/;/;x/;f/;;qFE3+E3+3+װ3+3+3+3+q3+6dDK PX@)pneU^ N@+~|eU^ NY@  +D7!#7!73!7322a2a>a2Jllll e #'+/dDK PX@Xnp~! f  e     eU]M@X~~! f  e     eU]MY@V,,(($$  ,/,/.-(+(+*)$'$'&% # #"!   "+D7#73733#7!!7!7!!7!7!!7!33333-mmCnnEDE^EDE_EDEE}HH}HHHHHHHHHHHHOCCChJG,l l3+lFGil l3+lFGl l3+lFG>l l3+lFGJl l3+hJGDl l3+hJGl l3+hJGDl l3+h?JGFl l3+ JGl l3+hJGFl l3+hGGl l3+hJGHl l3+hGl l3+6^&MM JGJl l3+lGKl l3+&lGLl l3+hGil l3+lGNl l3+&lGOl l3+ G@l l3+lJGPl l3+lJGQl l3+hJGRl l3+4GU, 3+ lJGUl l3+lFGWl l3+hJGVl l3+huGWl l3+hFGXl l3+lFGYl l3+lFG[l l3+lFG]l l3+ZG9 )&f 3+g ˰3+;I@F  8J_wK_xK_tL64/-"  ;; +"&'&&'&&'532654&'.546632&#"#3267IM ,V-1C0&8$32##3267#"&547#32654#"u-_MrJ\[3.+F0+X;`xd08UK36*">d:TAVh ,4ohk <5#."<,&!H6l,%3j!JKPX@]rK `xL@rK_zK `xLY@'&.,&3'3 %% +"&546733266773632#"&'#%26654&#"SI>C5!6( 0&,_p"GmJ>^2FT(:'!2  UH9'#<9`: rfE~b93/-xBi;)7-HR%Z,$/@,#J_zK]pL$$%' +#73&&54>323#7654&#""4#GiFE_12I"71'<'aW?7gQ03Y7Mj@ahO4<$:D(/!)2@   JK PX@.no  h _oK ] pLK PX@-o  h _oK ] pL@,  h _oK ] pLYY@20,*)'$"!!1! +33733273#7"###732654##32654&##YC C+/JD*3hRC6C&/9E'c51;%&.eeiyD6I^ E5cnjbbb+1C/74&)H"@arL +%"&&546323!6Yh-4, !  ((b8]8?A#.  p0+'7'7?T?T@S@S(2+@(eU]M +"&54633#"33DHIC~~W*-~bE@AC1S+)1( 2<@9eeU]M +"&54633#"335!DHIC~~W*-~bE@AC1S+)1~11(2   3+()2   3+(2(@%eU]M!#!+53254&##532#(~W*-~~DHIC1S+)1E@AC()29@6eeU]M!#!+53254&##532#5!(~W*-~~DHIC~1S+)1E@AC~11(2 ZEE3+( 2 3+NT.@+W_O +!3"&54632BP?NT1@.W_O +!3"&54632BPNT1@.W_O +!3"&54632BP NT1@.W_O +!3'"&54632BPNT-@*W_O +!3#"&54632BPNT.@+W_O +33"&54632NBP@NT1@.W_O +33"&54632NBPNT1@.W_O +33"&54632NBP NT1@.W_O +337"&54632NBPNT-@*W_O +333"&54632NBPNT 3+NT 3+NT*@'U]M+333#NBBNT 3+NT$@!U]M+333NBBI_<hVC{ +-  X^ b'X8!bS$S!T<5B ' 'Y'''' '+'&''* <5<5<5MX-tld<<Kcep<b<aRENZ~Z^4[KlK'BR,S,R,-,uR \))8)\I,SR, .\62=c'c<5'P''8'+' *@1yJ2#<5B@1W'<5{8{HBqbH@{[pS2BG{G_/ttttttd<<<<<<<I1EEEE4[^R,R,R,R,R,R,h,,-,-,-,-,))))A#\I,I,I,I,I,<5I\6\6\6\6StR,tR,tR,d<,d<,d<,d<,,R,-,-,-,-,-,<R <R <R <R \\))))RKc)e88))wG\\\\<I,<I,<I,<r,aaa    O.R.QE\6E\6E\6E\6E\6E\6~Z=4[4[f'tR,h,1I q~oK oq**J$,$%$.$ H$o(tl<eXp <bR4[0<^0W4[^,\o/h:^,lL,\I1o/8<&2-I,.S,j,.h:,((:4,o/h:I,h:4,Rd<KcRSVtPlcTSp<bd<RV0<^ZRuPe eR,I5=, Y,-, \6\6BghI,\S,,l4SP44-#433CF-,\ , )))bb\B\4~Z=~Z=~Z=4[84m84]xDA 8??D#D1 }A''X'< k5oG/8YM]*{2{I{b{LM'd)))49?Z.ptR,M<,E4-,\6vT(Bt>[wDDC<T 0W(:<I,Z"2Z"2<P,<y,@`+vT(Bd<,a35u4P88bS=T deL,SBR$`<e,d<,R4[24%LER-ZPZ\P\    ckhZSPEtR,tR,h,-,!-!-cT +#\6\6<I,<I,<I,d VVVZSPu#4W^DR,`k,\`0C@[W<w,R.N!tR,tR,tR,tR,tR,tR,tR,tR,tR,tR,tR,tR,-,-,-,-,-,-,-,-,))<I,<I,<I,<I,<I,<I,<I,<,<,<,<,<,E\6E\6E4E4E4E4E44[4[4[R^^^$N.S?PS=N=dd<,2PR,R!T<NU2e8)<;\<>4|,2SaS.@2.R6EVP.++%&.S#"'"/ l,Q/R>tR,)<I,E\6E\6E\6E\6E\6tR,tR,h,<R <R e8<I,<I,+#l,<R \tR,tR,-,-,))<I,<I,aaE\6E\6u\,&u)tR,-,<I,<I,<I,<I,4[|,|,td<( J!l X-#Kc)<R,a4.G0R,SSR,R,-W,)R R M,"(\6\\)o/\)44\\I,;, ",z j#II))1 )Q \~!:2.##PW<WM,h)R8R,L,, ,.Z.G.~ Ja a AAA|A]Q448ma{3g3]llRomBqB~BBo1 ) pMFA3<Y7nNNNNLNNn4JJBLL,8D,11"f ,d0$?Z,qTI,XP,!+>Qqg,)<,^Sd<pSdd<d<R,~Z=h(-I )m?*-.rN I0I,%4s:RW4> >C.FF<F`F`3\F"FQF<FFF\NFFYjbEpR{TR7AARjRjEMA%0=(qALAA|R:.|T|R  SXGLWMV= MH~GRgMMgy:SR,u\S`zRA"\oSs~SR, 8)\S 2R,R,R,-, ))\6A:RE3wLU==X0T5$*ALALWAA|RR3 S3J[[M(&(&k&d|UlSlSlSd<,R,R,R,R,R-,-,-- -,u<R \\\\\)n)e8e8e8))))lpp\\\\<I,<I,<I,<I,bSbSaaaa     R.R.E\-@\E\E\6E\6NZ2NZ2~Z=~Z=^^4[\.=R,f^,^,^,^,^,^,^,^,mu5F5FMMr0zC 5F 5F\\\\\\\\0C5F5FPPo/o/o/o/o/o/o/o/0C5F5FPPI,I,I,I,I,I,$01C5F5Fh:h:h:h:h:h:h:h:EPFnF~P4,4,4,4,4,4,4,4,30@C5F5FPP^,^,\\o/o/I,I,h:h:4,4,^,^,^,^,^,^,^,^,U5WFS5WFXMXM\\\\\\\\k0sC5 F5 F P P4,4,4,4,4,4,4,4,0C-52F5FPP^,^,^,^,^,^,^,ttzp-**\\\\\R4+R!4AAQo/o/oo'o"o/ R4AAQh:h:h:h:SSh:h:4[4[R4CAAA"4,4,4,4,4,JR'4YR649A,+'$'\h,?WE{]{[{[j|Yj<8( <"< <'N<<X;d<'EZ@1zG)baRlE<2Z(=,RxfxUE$AI`PE^,^,^,^,^,^,^,^,o/o/o/o/o/o/o/o/h:h:h:h:h:h:h:h:o/o/o/o/h:h:h:h:Pomqpwwwwxxxx?:)8Zg[ijA' pt`BVU$bBR>bX1vlvdeeeg><<bzb6H<%ebN~ZNNT]mY<L+L%gd<[deX6IuKjslAtE))L,  -)))HffX,x))R))0)n)"/eA\f.% X-,,p,h(r,888[),,S])R,,DD=SS']c2,+[*.J+")v,'qR8\l`+F,R,-,)\)\6s ///////////))))))II II P)P)P)P)P)ddd\\\\\\\\\\/u/u--o(o(o(o(o(o(o(o(o(o(o(,  o( ?0?12U5U5U5U5U5U5U5U5U5U5U5<>>>>>!AAAAAHtI-EaSpX=S1@}?RK>ua]<=<ZRRAg<<hjlX7E6: [^~4N#o/i`+G-4D,hKCT* X,0,fG [MLGHXG\,I,L )R \644qORnVKeKccKlH=/ QJ &(F"A  ax tm2 a aa=av&$(aTe[8>C  W Wo 1\\D,\4 uj\t-^W,:-uR*\\,,I*m,rr,,iXMeII)\6\3i&((lHlH2XR,Q VF=RA(>5NX"L:-'''' 52',6E 1 '+''' ''K''''''' ''{{{{{{{{ {{{?{G{{/{{7{D{M{3{AG?sG/_Gi7GxGG{{{{{{{{{{4JKK`W]V;B'5%} h4S4>4Q4BJD5dw;;%'wP4wMM+##<M"lhP#xxw;;%'\S47-4'5'5'5+I:( !? 4P4`+::W>1#CnITPTTPTD$DHBBB XBMMt?M00))22@XXXXXXXXXXXX/Fa!(Cd=X#. xxUxxMb,8xxOl0g48;JJAG'g&|$`')Q^+,NVae NZD*NNNN "&"(&&#' NNNN""&&(&#'%'.%%%NNNN%'%%%""#""""'%'%%%??NNNN%GGGGG3%%%%%%%%"%%-****+NNNN*fo0j}J";F6VH9OD8?<:<NP{ 4,Q5}bb~epbKJS:r9Gwr "+po.>EM rs:u}Xy}}|qC&G6&&4 ZU+:6Dl'HaZ(Z(Z(Z(Z(Z(Z(Z(NNNNNNNNNNNNNNNTTTT X pL x @ l D `<,Xtph (8P< ,!(!"#d$%P%&@&'@'t(L()t*X+L+,-`..p//h/0H11P222234t5<56<7,789::\:l;; >`>p>???@@@A4AlAAAABB@BdBCC(CLCpCCCDD$DDDE EDEhEEFFFGG(GLGHHHI I$I<ITK|KKKKKL L$L<LTM(M@MXMpMMMNTO$O<OTOlOOPdP|PPPPQ Q$QHQ`QQQQQRR8RPR`SSSSST T8TPUDUhUUUUUVV4VLVdVVW8XX,XDXhXXXXXYY(Y@YdY|YYZ Z0ZTZlZZZZ[[h[[[\\,\P\h\](^^(^@^d^|^^`tbb4bLbdb|bbbbcc0cHc`cccccddpe`eeeeeff8fPftfffffgg4gXg|ggggh hiTjLkll,lPlhllmm|mn,noooppqqqrr(rPrtrrrrrsTsdstst0t@tPtttuuuv vvvwwxhxxxxxyy(z{\{|}P}~d L\`4,d(@XpDLpx,xd0@P`p,<LP<<TlL 0tL04h`x(8H`p 8 l8Pt8H0x,`0PL<`P<pè`,xpd00000000000000$44L҄8Ը0TxՐըLxppܸ@|<<d\p<<hX@(x \0DTl lP  L   P  L,L`DLT$4Xpt(`$4Xp  $ H `   !D!h!!"L"#$$%%%&'()*+P,-.x/ /0T01124444455,5P5h55556 6,6P6h6666777H7h777778848L8p888899,9L9p99999: :$:H:`:::::;;@;`;;;;;<<8 >$>H>l>>>>?x@@ABCHDLEEtEEFG0H4HDIXIJJKLTLdM,MNNO@OPPPQR(SSTTUHUVWXTXdXtY|Z\[,\\]\^^^_`xa8abdc<cdeDeefpgghhiijk$kXkpll$lPlplllllmm mDm\mmmmmnn4nLnpnnnnoo$o<oTolooppqqr r0rTrlrrrrs s$s<sTsxst`uu,uDuhuuuuuvv4vXvpvvvvw w$wHw`wwwwwxxyPytyzD{||h}<}~~,~D~\~t~~~~(@X|Hh8X\L4@tT @x  8Xh,\lXh   P` hhXP tT@dXL`<LxD\`L0΄ψДlӐӴ DhԌ԰Tլ,֬8Xטר׸8؈ش4Tِ8\ڀ t\ܬD݌ݸ$DdހX0l|$Hl| `h4 0@L\T<0\(`X<dD|@h LDxDh8\(Lp$Hl  D h      @ d      < `      0 P p     dDHx, 8!`" "$\%'l)l*H*,T-|.01$2|3D446L6\789;@?0@lA|AAAB B0BTBxBBBCC,CPCtCCCDD(DLDpDDDEE$EHElEEEEF FDFhFFFFGGG@GdGGGGHHH@HdIJ|JJJKK$K<KTKxKKKL L0LTLxLLLLMM,MPMhMMMMNN(N@NdNNNNOOO0O\OOOOPP$P<PTPlPPPPPQ Q8QPQtQQQQRR(R@RdR|RRRRS S$SPSpSSSST T$THT`TTTTU U,UDU\UUUUUVV4VLVdV|VVVVWW0WHW`WWWWWXX,XDXhXXXXXYY4YXYxYYYYZZ Z8ZPZhZZZZZ[ [H[p[[[\\\0\H\`\x\\\]]8]`]x]]]]]^^ ^D^h^^^__0_X_p_____```<`````aa(aPahaaaaabb(bPbxbbbbcc(c@cXcpccccd$d<dTdldddddee,eTe|eeeff4fLfdf|fffffg g$g<gTglgggghhh8hThhhi i<iliiij j(jDj`j|jjjk k<klkkkl,lLllllllm m,mXmmmnnDntnnnnoo$o<oXo|ooopp`ptppqdqqqqqr r0rTrxrstxuxuuuuuvv,vPvxvwhxLyyyyyzzz4zLzpzzz{{|} },}D}d}|}}}~~,~D~0h(Lxp8| l$hL(XT(\lhplt@tTPd\X 8Ph(@Xp0H`xxDPhƬ0$$͸pdhX٤<ܴۨݼިH`x`x$H` \tT<TH`@|@`hxhh$<Tl$4D    h   8  (4Xh<4L\P XHX d! !`!"x##$%'D(`)*,*+\,8-X.<../x0 12 3@4$5t6(78X99::;<@<=>X? @p@ABC<CLC\C|D DDDEEE0EHFhHDIIJKM$MMMMNNN@NXN|NNO<OTOPPPPQQQRR4RDRRRSSS4SXSpSSTTTTUUUtVV$V|VVVVWW0WHWlWWXX4XXXYY(Y@YdYZ<ZZZZ[[\H\`\\\\\] ]]^_`D`a\aabb0bbcc,cPchdhdee<eTeleeff@fXfpffffg gdghh8hPhhhi i$iHi`ixiijj,jPjk@kl l,lmHmnoplq4r(r8rsTsuuv<vwxyyzd{D{|T}(}}~~d DX\t8h4Txl$XPl(d,(l(XpL ,Dx 4X|xL\Ht(4pxǔǴlX4̨@ͨ͘͸d`dՠhpHڬPTdtT`߼PlP04|x<D xlt8`    @$@0Pp<`8HXhx<(Hh(Hh(Hh @`  ( H h    !!(!H!!"4""#0#|##$$T%&h' ((T++-@.p//`0d1h11202P2p23 343p484445x====> >(>>?0@@@AB BBClCCCDEEFxGPH$HIIIJKKKKLL LMdMMNP QRdRS@SSSST TdTTTUUVVTVVVVWWTWxWWWXXY@YZhZ[<[T[\$\]D^^`^t^t^t^t^t^t^t^t^t^t^t^t^t_`<`acd,elflfgg0gh|hhi@iijjm$mDmnnnnnoprdtHt`uvvvwxy|4|}~L~\0|p T0x \ l X\HH XPX$p@h0xP,(lH(|(p `P< llL(pTTH0pTT(pL8 p\L$8H\p@P4<L\l|<Tt`|Ll(l ,p,l\T,´èLʌʨ8pXPl|ά,ϐϰДHxѼ0,PӌӠӰԘxh@א״\ٌ٤ڄ`x$ޤ4 Dh 0h,p$Hl Dh@d@d<`` @L@D0 p,H\|,d8\d8$\4X| 0Tl Dh@d<\TH0dl  $ X  8 X x  T t   h @ xL<\ - m ^ ^ p < *  &| D * ( B8 >z <  4Copyright 2015 Google Inc. All Rights Reserved.Noto SansBold Italic2.000;GOOG;NotoSans-BoldItalicNoto Sans Bold ItalicVersion 2.000;GOOG;noto-source:20170915:90ef993387c0; ttfautohint (v1.7)NotoSans-BoldItalicNoto is a trademark of Google Inc.Monotype Imaging Inc.Monotype Design TeamDesigned by Monotype design team.http://www.google.com/get/noto/http://www.monotype.com/studioThis Font Software is licensed under the SIL Open Font License, Version 1.1. This Font Software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the SIL Open Font License for the specific language, permissions and limitations governing your use of this Font Software.http://scripts.sil.org/OFL2   !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`a  bcdefghjikmlnoqprsutvwxzy{}|~    !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~                           ! " # $ % & ' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; < = > ? @ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ _ ` a b c d e f g h i j k l m n o p q r s t u v w x y z { | } ~                            ! " # $ % & ' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; < = > ? @ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ _ ` a b c d e f g h i j k l m n o p q r s t u v w x y z { | } ~                            ! " # $ % & ' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; < = > ? @ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ _ ` a b c d e f g h i j k l m n o p q r s t u v w x y z { | } ~                            ! " # $ % & ' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; < = > ? @ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ _ ` a b c d e f g h i j k l m n o p q r s t u v w x y z { | } ~  NULLCRuni00A0uni00AD overscoreuni00B2uni00B3uni03BCuni00B9AmacronamacronAbreveabreveAogonekaogonek Ccircumflex ccircumflexCdotcdotDcarondcaronDcroatEmacronemacronEbreveebreve Edotaccent edotaccentEogonekeogonekEcaronecaron Gcircumflex gcircumflexGdotgdotuni0122uni0123 Hcircumflex hcircumflexHbarhbarItildeitildeImacronimacronIbreveibreveIogonekiogonekIJij Jcircumflex jcircumflexuni0136uni0137 kgreenlandicLacutelacuteuni013Buni013CLcaronlcaronLdotldotNacutenacuteuni0145uni0146Ncaronncaron napostropheEngengOmacronomacronObreveobreve Ohungarumlaut ohungarumlautRacuteracuteuni0156uni0157RcaronrcaronSacutesacute Scircumflex scircumflexuni021Auni021BTcarontcaronTbartbarUtildeutildeUmacronumacronUbreveubreveUringuring Uhungarumlaut uhungarumlautUogonekuogonek Wcircumflex wcircumflex Ycircumflex ycircumflexZacutezacute Zdotaccent zdotaccentlongs Aringacute aringacuteAEacuteaeacute Oslashacute oslashacuteuni0218uni0219tonos dieresistonos Alphatonos anoteleia EpsilontonosEtatonos Iotatonos Omicrontonos Upsilontonos OmegatonosiotadieresistonosAlphaBetaGammaEpsilonZetaEtaThetaIotaKappaLambdaMuNuXiOmicronPiRhoSigmaTauUpsilonPhiChiPsi IotadieresisUpsilondieresis alphatonos epsilontonosetatonos iotatonosupsilondieresistonosalphabetagammadeltaepsilonzetaetathetaiotakappalambdanuxiomicronrhosigma1sigmatauupsilonphichipsiomega iotadieresisupsilondieresis omicrontonos upsilontonos omegatonos afii10023 afii10051 afii10052 afii10053 afii10054 afii10055 afii10056 afii10057 afii10058 afii10059 afii10060 afii10061 afii10062 afii10145 afii10017 afii10018 afii10019 afii10020 afii10021 afii10022 afii10024 afii10025 afii10026 afii10027 afii10028 afii10029 afii10030 afii10031 afii10032 afii10033 afii10034 afii10035 afii10036 afii10037 afii10038 afii10039 afii10040 afii10041 afii10042 afii10043 afii10044 afii10045 afii10046 afii10047 afii10048 afii10049 afii10065 afii10066 afii10067 afii10068 afii10069 afii10070 afii10072 afii10073 afii10074 afii10075 afii10076 afii10077 afii10078 afii10079 afii10080 afii10081 afii10082 afii10083 afii10084 afii10085 afii10086 afii10087 afii10088 afii10089 afii10090 afii10091 afii10092 afii10093 afii10094 afii10095 afii10096 afii10097 afii10071 afii10099 afii10100 afii10101 afii10102 afii10103 afii10104 afii10105 afii10106 afii10107 afii10108 afii10109 afii10110 afii10193 afii10050 afii10098WgravewgraveWacutewacute Wdieresis wdieresisYgraveygrave afii00208 underscoredbl quotereversedminutesecond exclamdbl nsuperior afii08941pesetaEuro afii61248 afii61289 afii61352uni03A9 estimated oneeighth threeeighths fiveeighths seveneighthsuni0394 cyrillicbrevecaroncommaaccentcommaaccentrotateuni2074uni2075uni2077uni2078uni2000uni2001uni2002uni2003uni2004uni2005uni2006uni2007uni2008uni2009uni200Auni200BuniFEFFuniFFFCuniFFFDuni01F0uni02BCuni03D1uni03D2uni03D6uni1E3Euni1E3Funi1E00uni1E01uni02F3OhornohornUhornuhornhookuni0400uni040Duni0450uni045Duni0460uni0461uni0462uni0463uni0464uni0465uni0466uni0467uni0468uni0469uni046Auni046Buni046Cuni046Duni046Euni046Funi0470uni0471uni0472uni0473uni0474uni0475uni0476uni0477uni0478uni0479uni047Auni047Buni047Cuni047Duni047Euni047Funi0480uni0481uni0482uni0488uni0489uni048Auni048Buni048Cuni048Duni048Euni048Funi0492uni0493uni0494uni0495uni0496uni0497uni0498uni0499uni049Auni049Buni049Cuni049Duni049Euni049Funi04A0uni04A1uni04A2uni04A3uni04A4uni04A5uni04A6uni04A7uni04A8uni04A9uni04AAuni04ABuni04ACuni04ADuni04AEuni04AFuni04B0uni04B1uni04B2uni04B3uni04B4uni04B5uni04B6uni04B7uni04B8uni04B9uni04BAuni04BBuni04BCuni04BDuni04BEuni04BFuni04C0uni04C1uni04C2uni04C3uni04C4uni04C5uni04C6uni04C7uni04C8uni04C9uni04CAuni04CBuni04CCuni04CDuni04CEuni04CFuni04D0uni04D1uni04D2uni04D3uni04D4uni04D5uni04D6uni04D7uni04D8uni04D9uni04DAuni04DBuni04DCuni04DDuni04DEuni04DFuni04E0uni04E1uni04E2uni04E3uni04E4uni04E5uni04E6uni04E7uni04E8uni04E9uni04EAuni04EBuni04ECuni04EDuni04EEuni04EFuni04F0uni04F1uni04F2uni04F3uni04F4uni04F5uni04F6uni04F7uni04F8uni04F9uni04FAuni04FBuni04FCuni04FDuni04FEuni04FFuni0500uni0501uni0502uni0503uni0504uni0505uni0506uni0507uni0508uni0509uni050Auni050Buni050Cuni050Duni050Euni050Funi0510uni0511uni0512uni0513uni1EA0uni1EA1uni1EA2uni1EA3uni1EA4uni1EA5uni1EA6uni1EA7uni1EA8uni1EA9uni1EAAuni1EABuni1EACuni1EADuni1EAEuni1EAFuni1EB0uni1EB1uni1EB2uni1EB3uni1EB4uni1EB5uni1EB6uni1EB7uni1EB8uni1EB9uni1EBAuni1EBBuni1EBCuni1EBDuni1EBEuni1EBFuni1EC0uni1EC1uni1EC2uni1EC3uni1EC4uni1EC5uni1EC6uni1EC7uni1EC8uni1EC9uni1ECAuni1ECBuni1ECCuni1ECDuni1ECEuni1ECFuni1ED0uni1ED1uni1ED2uni1ED3uni1ED4uni1ED5uni1ED6uni1ED7uni1ED8uni1ED9uni1EDAuni1EDBuni1EDCuni1EDDuni1EDEuni1EDFuni1EE0uni1EE1uni1EE2uni1EE3uni1EE4uni1EE5uni1EE6uni1EE7uni1EE8uni1EE9uni1EEAuni1EEBuni1EECuni1EEDuni1EEEuni1EEFuni1EF0uni1EF1uni1EF4uni1EF5uni1EF6uni1EF7uni1EF8uni1EF9uni20ABcircumflexacutecombcircumflexgravecombcircumflexhookcombcircumflextildecombbreveacutecombbrevegravecomb brevehookcombbrevetildecombcyrillichookleftcyrillicbighookUCuni0162uni0163uni0180uni0181uni0182uni0183uni0184uni0185uni0186uni0187uni0188uni0189uni018Auni018Buni018Cuni018Duni018Euni018Funi0190uni0191uni0193uni0194uni0195uni0196uni0197uni0198uni0199uni019Auni019Buni019Cuni019Duni019Euni019Funi01A2uni01A3uni01A4uni01A5uni01A6uni01A7uni01A8uni01A9uni01AAuni01ABuni01ACuni01ADuni01AEuni01B1uni01B2uni01B3uni01B4uni01B5uni01B6uni01B7uni01B8uni01B9uni01BAuni01BBuni01BCuni01BDuni01BEuni01BFuni01C0uni01C1uni01C2uni01C3uni01C4uni01C5uni01C6uni01C7uni01C8uni01C9uni01CAuni01CBuni01CCuni01CDuni01CEuni01CFuni01D0uni01D1uni01D2uni01D3uni01D4uni01D5uni01D6uni01D7uni01D8uni01D9uni01DAuni01DBuni01DCuni01DEuni01DFuni01E0uni01E1uni01E2uni01E3uni01E4uni01E5uni01E6uni01E7uni01E8uni01E9uni01EAuni01EBuni01ECuni01EDuni01EEuni01EFuni01F1uni01F2uni01F3uni01F4uni01F5uni01F6uni01F7uni01F8uni01F9uni0200uni0201uni0202uni0203uni0204uni0205uni0206uni0207uni0208uni0209uni020Auni020Buni020Cuni020Duni020Euni020Funi0210uni0211uni0212uni0213uni0214uni0215uni0216uni0217uni021Cuni021Duni021Euni021Funi0220uni0221uni0222uni0223uni0224uni0225uni0226uni0227uni0228uni0229uni022Auni022Buni022Cuni022Duni022Euni022Funi0230uni0231uni0232uni0233uni0234uni0235uni0236uni0238uni0239uni023Auni023Buni023Cuni023Duni023Euni023Funi0240uni0241uni0242uni0243uni0244uni0245uni0246uni0247uni0248uni0249uni024Auni024Buni024Cuni024Duni024Euni024Funi0250uni0251uni0252uni0253uni0254uni0255uni0256uni0257uni0258uni0259uni025Buni025Euni025Funi0260uni0261uni0262uni0263uni0264uni0265uni0266uni0267uni0268 iotaLatinuni026Auni026Buni026Cuni026Duni026Euni026Funi0270uni0271uni0272uni0273uni0274uni0275uni0276 omegacloseduni0278uni0279uni027Auni027Buni027Cuni027Duni027Euni027Funi0280uni0281uni0282uni0283uni0284uni0285uni0286uni0287uni0288uni0289uni028Auni028Buni028Cuni028Duni028Euni028Funi0290uni0291uni0292uni0293uni0294uni0295 glottalturneduni0297uni0298uni0299uni029Auni029Buni029Cuni029Duni029Euni029Funi02A0uni02A1uni02A2dzliguni02A4 dzligcurltsliguni02A7 tcligcurluni02A9uni02AAuni02ABuni02ACuni02ADuni02AEuni02AFuni02B0uni02B1uni02B2uni02B3uni02B4uni02B5uni02B6uni02B7uni02B8uni02B9uni02BAuni02BBuni02BDuni02BEuni02BFuni02C0uni02C1uni02C2uni02C3uni02C4uni02C5uni02C8uni02CAuni02CBuni02CCuni02CDuni02CEuni02CFuni02D0uni02D1uni02D2uni02D3uni02D4uni02D5uni02D6uni02D7uni02DFuni02E0uni02E1uni02E2uni02E3uni02E4uni02E5uni02E6uni02E7uni02E8uni02E9uni02EAuni02EBuni02ECuni02EDuni02EEuni02EFuni02F0uni02F1uni02F2uni02F4uni02F5uni02F6uni02F7uni02F8uni02F9uni02FAuni02FBuni02FCuni02FDuni02FEuni02FF hookabovecombuni0374uni0375uni037Auni037Buni037Cuni037Duni037Euni03D0uni03D3uni03D4phi1uni03D7uni03D8uni03D9uni03DAuni03DBuni03DCuni03DDuni03DEuni03DFuni03E0uni03E1uni03F0uni03F1uni03F2uni03F3uni03F4uni03F5uni03F6uni03F7uni03F8uni03F9uni03FAuni03FBuni03FCuni03FDuni03FEuni03FFuni051Auni051Buni051Cuni051Duni1D00uni1D01uni1D02uni1D03uni1D04uni1D05uni1D06uni1D07uni1D08uni1D09uni1D0Auni1D0Buni1D0Cuni1D0Duni1D0Euni1D0Funi1D10uni1D11uni1D12uni1D13uni1D14uni1D15uni1D16uni1D17uni1D18uni1D19uni1D1Auni1D1Buni1D1Cuni1D1Duni1D1Euni1D1Funi1D20uni1D21uni1D22uni1D23uni1D24uni1D25uni1D26uni1D27uni1D28uni1D29uni1D2Auni1D2Buni1D2Cuni1D2Duni1D2Euni1D2Funi1D30uni1D31uni1D32uni1D33uni1D34uni1D35uni1D36uni1D37uni1D38uni1D39uni1D3Auni1D3Buni1D3Cuni1D3Duni1D3Euni1D3Funi1D40uni1D41uni1D42uni1D43uni1D44uni1D45uni1D46uni1D47uni1D48uni1D49uni1D4Auni1D4Buni1D4Cuni1D4Duni1D4Euni1D4Funi1D50uni1D51uni1D52uni1D53uni1D54uni1D55uni1D56uni1D57uni1D58uni1D59uni1D5Auni1D5Buni1D5Cuni1D5Duni1D5Euni1D5Funi1D60uni1D61uni1D62uni1D63uni1D64uni1D65uni1D66uni1D67uni1D68uni1D69uni1D6Auni1D6Buni1D6Cuni1D6Duni1D6Euni1D6Funi1D70uni1D71uni1D72uni1D73uni1D74uni1D75uni1D76uni1D77uni1D78uni1D79uni1D7Auni1D7Buni1D7Cuni1D7Duni1D7Euni1D7Funi1D80uni1D81uni1D82uni1D83uni1D84uni1D85uni1D86uni1D87uni1D88uni1D89uni1D8Auni1D8Buni1D8Cuni1D8Duni1D8Euni1D8Funi1D90uni1D91uni1D92uni1D93uni1D94uni1D95uni1D96uni1D97uni1D98uni1D99uni1D9Auni1D9Buni1D9Cuni1D9Duni1D9Euni1D9Funi1DA0uni1DA1uni1DA2uni1DA3uni1DA4uni1DA5uni1DA6uni1DA7uni1DA8uni1DA9uni1DAAuni1DABuni1DACuni1DADuni1DAEuni1DAFuni1DB0uni1DB1uni1DB2uni1DB3uni1DB4uni1DB5uni1DB6uni1DB7uni1DB8uni1DB9uni1DBAuni1DBBuni1DBCuni1DBDuni1DBEuni1DBFuni1E02uni1E03uni1E04uni1E05uni1E06uni1E07uni1E08uni1E09uni1E0Auni1E0Buni1E0Cuni1E0Duni1E0Euni1E0Funi1E10uni1E11uni1E12uni1E13uni1E14uni1E15uni1E16uni1E17uni1E18uni1E19uni1E1Auni1E1Buni1E1Cuni1E1Duni1E1Euni1E1Funi1E20uni1E21uni1E22uni1E23uni1E24uni1E25uni1E26uni1E27uni1E28uni1E29uni1E2Auni1E2Buni1E2Cuni1E2Duni1E2Euni1E2Funi1E30uni1E31uni1E32uni1E33uni1E34uni1E35uni1E36uni1E37uni1E38uni1E39uni1E3Auni1E3Buni1E3Cuni1E3Duni1E40uni1E41uni1E42uni1E43uni1E44uni1E45uni1E46uni1E47uni1E48uni1E49uni1E4Auni1E4Buni1E4Cuni1E4Duni1E4Euni1E4Funi1E50uni1E51uni1E52uni1E53uni1E54uni1E55uni1E56uni1E57uni1E58uni1E59uni1E5Auni1E5Buni1E5Cuni1E5Duni1E5Euni1E5Funi1E60uni1E61uni1E62uni1E63uni1E64uni1E65uni1E66uni1E67uni1E68uni1E69uni1E6Auni1E6Buni1E6Cuni1E6Duni1E6Euni1E6Funi1E70uni1E71uni1E72uni1E73uni1E74uni1E75uni1E76uni1E77uni1E78uni1E79uni1E7Auni1E7Buni1E7Cuni1E7Duni1E7Euni1E7Funi1E86uni1E87uni1E88uni1E89uni1E8Auni1E8Buni1E8Cuni1E8Duni1E8Euni1E8Funi1E90uni1E91uni1E92uni1E93uni1E94uni1E95uni1E96uni1E97uni1E98uni1E99uni1E9Auni1E9Buni1F00uni1F01uni1F02uni1F03uni1F04uni1F05uni1F06uni1F07uni1F08uni1F09uni1F0Auni1F0Buni1F0Cuni1F0Duni1F0Euni1F0Funi1F10uni1F11uni1F12uni1F13uni1F14uni1F15uni1F18uni1F19uni1F1Auni1F1Buni1F1Cuni1F1Duni1F20uni1F21uni1F22uni1F23uni1F24uni1F25uni1F26uni1F27uni1F28uni1F29uni1F2Auni1F2Buni1F2Cuni1F2Duni1F2Euni1F2Funi1F30uni1F31uni1F32uni1F33uni1F34uni1F35uni1F36uni1F37uni1F38uni1F39uni1F3Auni1F3Buni1F3Cuni1F3Duni1F3Euni1F3Funi1F40uni1F41uni1F42uni1F43uni1F44uni1F45uni1F48uni1F49uni1F4Auni1F4Buni1F4Cuni1F4Duni1F50uni1F51uni1F52uni1F53uni1F54uni1F55uni1F56uni1F57uni1F59uni1F5Buni1F5Duni1F5Funi1F60uni1F61uni1F62uni1F63uni1F64uni1F65uni1F66uni1F67uni1F68uni1F69uni1F6Auni1F6Buni1F6Cuni1F6Duni1F6Euni1F6Funi1F70uni1F71uni1F72uni1F73uni1F74uni1F75uni1F76uni1F77uni1F78uni1F79uni1F7Auni1F7Buni1F7Cuni1F7Duni1F80uni1F81uni1F82uni1F83uni1F84uni1F85uni1F86uni1F87uni1F88uni1F89uni1F8Auni1F8Buni1F8Cuni1F8Duni1F8Euni1F8Funi1F90uni1F91uni1F92uni1F93uni1F94uni1F95uni1F96uni1F97uni1F98uni1F99uni1F9Auni1F9Buni1F9Cuni1F9Duni1F9Euni1F9Funi1FA0uni1FA1uni1FA2uni1FA3uni1FA4uni1FA5uni1FA6uni1FA7uni1FA8uni1FA9uni1FAAuni1FABuni1FACuni1FADuni1FAEuni1FAFuni1FB0uni1FB1uni1FB2uni1FB3uni1FB4uni1FB6uni1FB7uni1FB8uni1FB9uni1FBAuni1FBBuni1FBCuni1FBDuni1FBEuni1FBFuni1FC0uni1FC1uni1FC2uni1FC3uni1FC4uni1FC6uni1FC7uni1FC8uni1FC9uni1FCAuni1FCBuni1FCCuni1FCDuni1FCEuni1FCFuni1FD0uni1FD1uni1FD2uni1FD3uni1FD6uni1FD7uni1FD8uni1FD9uni1FDAuni1FDBuni1FDDuni1FDEuni1FDFuni1FE0uni1FE1uni1FE2uni1FE3uni1FE4uni1FE5uni1FE6uni1FE7uni1FE8uni1FE9uni1FEAuni1FEBuni1FECuni1FEDuni1FEEuni1FEFuni1FF2uni1FF3uni1FF4uni1FF6uni1FF7uni1FF8uni1FF9uni1FFAuni1FFBuni1FFCuni1FFDuni1FFEuni200Cuni200Duni200Euni200Funi2012uni2016uni201Funi202Auni202Buni202Cuni202Duni202Euni202Funi2034uni203Euni205Euni206Auni206Buni206Cuni206Duni206Euni206Funi2070uni2076uni2079uni2090uni2091uni2092uni2093uni2094uni20A0uni20A1uni20A2uni20A5uni20A6uni20A8uni20A9uni20ADuni20AEuni20AFuni20B0uni20B1uni20B2uni20B3uni20B4uni20B5uni20B9uni20F0uni2117uni214Duni214Euni2153uni2154uni2184uni2C60uni2C61uni2C62uni2C63uni2C64uni2C65uni2C66uni2C67uni2C68uni2C69uni2C6Auni2C6Buni2C6Cuni2C6Duni2C71uni2C72uni2C73uni2C74uni2C75uni2C76uni2C77uni2E17uniA717uniA718uniA719uniA71AuniA71BuniA71CuniA71DuniA71EuniA71FuniA720uniA721uniA788uniA789uniA78AuniA78BuniA78C dieresisacute dieresisgraveuniFE20uniFE21uniFE22uniFE23uni03B1030403130300uni03B1030403130301uni03B1030403140300uni03B1030403140301uni03B1030603130300uni03B1030603130301uni03B1030603140300uni03B1030603140301uni03B9030403130300uni03B9030403130301uni03B9030403140300uni03B9030403140301uni03B9030603130300uni03B9030603130301uni03B9030603140300uni03B9030603140301uni03C5030403130300uni03C5030403130301uni03C5030403140300uni03C5030403140301uni03C5030603130300uni03C5030603130301uni03C5030603140300uni03C5030603140301uni03B9030803040300uni03B9030803040301uni03B9030803060300uni03B9030803060301uni03C5030803040300uni03C5030803040301uni03C5030803060300uni03C5030803060301Eng.alt1Eng.alt2Eng.alt3 uni1FCD02C9 uni1FCE02C9 uni1FDD02C9 uni1FDE02C9dotacutecarondotmacrondieresis tildedieresis tildeacute macrongrave macronacute dieresiscarondieresismacron tildemacron dotmacron dotmacron.capuni030103060308uni030003060308uni030103040308uni030003040308 uni1FDE0306 uni1FDD0306 uni1FCE0306 uni1FCD0306uni0514uni0515uni0516uni0517uni0518uni0519uni051Euni051Funi0520uni0521uni0522uni0523uni0524uni0525uni0526uni0527cyrillic_otmarkuni20BAuni1EFAuni2C6Euni1E9ETurnedauni1EFCuni1EFEuniA722uniA724uniA726uniA728uniA72AuniA72CuniA72EuniA732uniA734uniA736uniA738uniA73AuniA73CuniA73EuniA740uniA742uniA744uniA746uniA748uniA74AuniA74CuniA74EuniA750uniA752uniA754uniA756uniA758uniA75AuniA75CuniA75EuniA760uniA764uniA766uniA768uniA76AuniA76CuniA76EuniA779uniA77BuniA77DuniA77EuniA780uniA782uniA784uniA786uniA78DuniA790uniA792uniA7A0uniA7A2uniA7A4uniA7A6uniA7A8uniA7AAuniA7ABuniA7ACuniA7ADuniA7B0uniA7B1uniA7B2uniA7B3uniA7B4uniA7B6Aogonek.loclNAVEogonek.loclNAVIogonek.loclNAVUogonek.loclNAVLcommaaccent.loclMAHNcommaaccent.loclMAHTurnedeafii10103dotlessafii10105dotless deltalatinuni2C78uni025Cuni025Duni01DDuni025Aiogonekdotlessuni0237uni1EFBuni1E9Cuni1E9Duni2C7A subscriptjuni2C79uni0249dotlessuni029Ddotlessuni02B2dotlessuni03F3dotlessuni1D62dotlessuni1D96dotlessuni1DA4dotlessuni1DA8dotlessuni1E2Ddotlessuni1ECBdotlessuniA723uniA725uniA727uniA729uniA72BuniA72DuniA72FuniA730uniA731uniA733uniA735uniA737uniA739uniA73BuniA73DuniA73FuniA741uniA743uniA745uniA747uniA749uniA74BuniA74DuniA74FuniA751uniA753uniA755uniA757uniA759uniA75BuniA75DuniA75FuniA761uniA765uniA767uniA769uniA76BuniA76DuniA76FuniA771uniA772uniA773uniA774uniA775uniA776uniA777uniA778uniA77AuniA77CuniA77FuniA781uniA783uniA785uniA787uniA78EuniA791uniA793uniA7A1uniA7A3uniA7A5uniA7A7uniA7A9uniA7B5uniA7B7uniA7FAuni1EFDuni1EFFaogonek.loclNAVeogonek.loclNAVlcommaaccent.loclMAHncommaaccent.loclMAHiogonek.loclNAVuogonek.loclNAVf_ff_f_if_f_lf_if_llongs_ts_ta.sc aacute.sc abreve.scacircumflex.sc adieresis.sc agrave.sc amacron.sc aogonek.scaring.sc aringacute.sc atilde.scae.sc aeacute.scb.scc.sc cacute.sc ccaron.sc ccedilla.scccircumflex.sccdot.scd.sceth.sc dcaron.sc dcroat.sce.sc eacute.sc ebreve.sc ecaron.scecircumflex.sc edieresis.sc edotaccent.sc egrave.sc emacron.sc eogonek.scf.scg.sc gbreve.scgcircumflex.scgcommaaccent.scgdot.sch.schbar.schcircumflex.sci.sc iacute.sc ibreve.scicircumflex.sc idieresis.sc idotaccent.sc igrave.scij.sc imacron.sc iogonek.sc itilde.scj.scjcircumflex.sck.sckcommaaccent.scl.sc lacute.sc lcaron.sclcommaaccent.scldot.sc lslash.scm.scn.sc nacute.sc ncaron.scncommaaccent.sceng.sc ntilde.sco.sc oacute.sc obreve.scocircumflex.sc odieresis.sc ograve.scohungarumlaut.sc omacron.sc oslash.scoslashacute.sc otilde.scoe.scp.scthorn.scq.scr.sc racute.sc rcaron.scrcommaaccent.scs.sc sacute.sc scaron.sc scedilla.scscircumflex.scscommaaccent.sc germandbls.sct.sctbar.sc tcaron.sc tcedilla.sctcommaaccent.scu.sc uacute.sc ubreve.scucircumflex.sc udieresis.sc ugrave.scuhungarumlaut.sc umacron.sc uogonek.scuring.sc utilde.scv.scw.sc wacute.scwcircumflex.sc wdieresis.sc wgrave.scx.scy.sc yacute.scycircumflex.sc ydieresis.sc ygrave.scz.sc zacute.sc zcaron.sc zdotaccent.scuni2071uniA78FuniA7F7uniA7FBuniA7FCuniA7FDuniA7FEuniA7FFuni0528uni052Auni052Cuni052EuniA640uniA642uniA644uniA646uniA648uniA64AuniA64CuniA64EuniA650uniA652uniA654uniA656uniA658uniA65AuniA65CuniA65EuniA660uniA662uniA664uniA666uniA668uniA66AuniA66CuniA680uniA682uniA684uniA686uniA688uniA68AuniA68CuniA68EuniA690uniA692uniA694uniA696uniA698uniA69Auni0529uni052Buni052Duni052Funi1C80uni1C81uni1C82uni1C83uni1C84uni1C85uni1C86uni1C87uni1C88uniA641uniA643uniA645uniA647uniA649uniA64BuniA64DuniA64FuniA651uniA653uniA655uniA657uniA659uniA65BuniA65DuniA65FuniA661uniA663uniA665uniA667uniA669uniA66BuniA66DuniA681uniA683uniA685uniA687uniA689uniA68BuniA68DuniA68FuniA691uniA693uniA695uniA697uniA699uniA69Bafii10066.loclSRBafii10068.loclSRBafii10069.loclSRBafii10081.loclSRBafii10084.loclSRBafii10090.loclSRBuniA66EuniA67FuniA69CuniA69Duni2126uni0370uni0372uni0376uni03CFuni037Funi0371uni0373uni0377 uni03D0.altCfrakturHfrakturIfrakturRfrakturZfrakturuniA762uniA763uni212Cuni210Buni2110uni2112PiDoubleStruckuni211BTurnedFuni212B CDoubleStruck HDoubleStruck NDoubleStruck PDoubleStruck QDoubleStruck RDoubleStruck ZDoubleStruckItalicDDoubleStruckGammaDoubleStruckuni2107uni212Auni2130uni2131uni2133uniA796uniA798uniA79AuniA79CuniA79EItalicdDoubleStruckItaliceDoubleStruckItaliciDoubleStruckItalicjDoubleStruckgammaDoubleStruckpiDoubleStruckuni210Euni210FscriptescriptoscriptguniA794uniA795uniA797uniA799uniA79BuniA79DuniA79FuniAB30uniAB31uniAB32uniAB33uniAB34uniAB35uniAB36uniAB37uniAB38uniAB39uniAB3AuniAB3BuniAB3CuniAB3DuniAB3EuniAB3FuniAB40uniAB41uniAB42uniAB43uniAB44uniAB45uniAB46uniAB47uniAB48uniAB49uniAB4AuniAB4BuniAB4CuniAB4DuniAB4EuniAB4FuniAB50uniAB51uniAB52uniAB53uniAB54uniAB55uniAB56uniAB57uniAB58uniAB59uniAB5AuniAB64uni2095uni2096uni2097uni2098uni2099uni209Auni209Buni209CuniA770uniA7F8uniA7F9uniAB5CuniAB5DuniAB5EuniAB5Funi2E2Fzero.lfone.lftwo.lfthree.lffour.lffive.lfsix.lfseven.lfeight.lfnine.lfzero.osfone.osftwo.osf three.osffour.osffive.osfsix.osf seven.osf eight.osfnine.osf zero.slash zero.tosfone.tosftwo.tosf three.tosf four.tosf five.tosfsix.tosf seven.tosf eight.tosf nine.tosf zero.dnomone.dnomtwo.dnom three.dnom four.dnom five.dnomsix.dnom seven.dnom eight.dnom nine.dnom zero.numrone.numrtwo.numr three.numr four.numr five.numrsix.numr seven.numr eight.numr nine.numruni215Funi2189uni2155uni2156uni2157uni2158uni2159uni215Auni2150uni2151uni2152uni2080uni2081uni2082uni2083uni2084uni2085uni2086uni2087uni2088uni2089uni2042uni204Cuni204Duni2045uni2046caretuni2041uni2040uni2050uni2E36uni2E37uni205Cuni2E13uni2E16uni2E08downwardsancorauni2E0Euni2049uni2E2Duni2059uni2055uni2E10uni205Buni2058uni2027uni2043uni2E12uni2E18uni2054uni2E04uni2E1Cuni2E0Cuni2E02uni2E09uni2E20uni204Eonedotenleaderonedotovertwodotspunctuationuni2E19uni2E0Funi2047uni2048uni2E34uni2E33uni2E07uni2E06uni2E0Buni203Buni2E11reversedparagraphreversedquestionmarkuni204Funi2E01uni2E00uni2E05uni2E1Duni2E0Duni2E03uni2E0Auni2E21uni2E30squaredfourdotpunctuationuni2053uni2056uni2E1Euni2E1Funi2E1Buni204Auni2E39uni205Duni2E32uni2E38uni2E35uni2051twodotenleaderuni205Atwodotsoveronedotpunctuationuni203Funi2023uni2E3Cuni2E3Duni2E3Euni2E3Funi2E41uniA673 upwardsancorauni2E31uni208Duni208Ebrackhalfbottomleftbrackhalfbottomrightbrackhalftopleftbrackhalftoprightleftdoubleparenthesisrightdoubleparenthesisuni2E26uni2E27uni207Duni207Euni2E1Auni2010uni2011uni2E3Buni2E3Auni2E40uni2036uni2035uni2057uni2037uni2E42 braceleft.sc braceright.scbracketleft.scbracketright.sc exclam.sc exclamdbl.sc exclamdown.sc parenleft.sc parenright.sc question.scquestiondown.scuniA92EuniA67Euni205Funi2028uni2029uni2061uni2064uni2063uni2062uni2066uni2067uni2068uni2069uni2060uni20B6uni20BCuni20BDuni20AAuni20B7uni20B8uni20BBuni20BEuni2127uni2135uni214Buni2136uni2052uni2138uni208Cuni207Cuni2137uni208Buni207Buni00B5uni2031uni208Auni207AreversedSansSerifLsummationDoubleStruckturnedSansSerifGturnedSansSerifLturnedSansSerifYRotatedQuni2100uni2101uni2106uni2103uni2104uni213Buni2109uni2139uni203Duni2114uni2125uni214C prescriptionuni214Auni211Funi2108uni2120symbolforsamaritansourceuni2121uni2123 weierstrassuni02DEuni02E5_uni02E5_uni02E9uni02E5_uni02E5_uni02E6uni02E5_uni02E5_uni02E8uni02E5_uni02E5_uni02E7uni02E5_uni02E9uni02E5_uni02E9_uni02E5uni02E5_uni02E9_uni02E9uni02E5_uni02E9_uni02E6uni02E5_uni02E9_uni02E8uni02E5_uni02E9_uni02E7uni02E5_uni02E6uni02E5_uni02E6_uni02E5uni02E5_uni02E6_uni02E9uni02E5_uni02E6_uni02E6uni02E5_uni02E6_uni02E8uni02E5_uni02E6_uni02E7uni02E5_uni02E8uni02E5_uni02E8_uni02E5uni02E5_uni02E8_uni02E9uni02E5_uni02E8_uni02E6uni02E5_uni02E8_uni02E8uni02E5_uni02E8_uni02E7uni02E5_uni02E7uni02E5_uni02E7_uni02E5uni02E5_uni02E7_uni02E9uni02E5_uni02E7_uni02E6uni02E5_uni02E7_uni02E8uni02E5_uni02E7_uni02E7uni02E9_uni02E5uni02E9_uni02E5_uni02E5uni02E9_uni02E5_uni02E9uni02E9_uni02E5_uni02E6uni02E9_uni02E5_uni02E8uni02E9_uni02E5_uni02E7uni02E9_uni02E9_uni02E5uni02E9_uni02E9_uni02E6uni02E9_uni02E9_uni02E8uni02E9_uni02E9_uni02E7uni02E9_uni02E6uni02E9_uni02E6_uni02E5uni02E9_uni02E6_uni02E9uni02E9_uni02E6_uni02E6uni02E9_uni02E6_uni02E8uni02E9_uni02E6_uni02E7uni02E9_uni02E8uni02E9_uni02E8_uni02E5uni02E9_uni02E8_uni02E9uni02E9_uni02E8_uni02E6uni02E9_uni02E8_uni02E8uni02E9_uni02E8_uni02E7uni02E9_uni02E7uni02E9_uni02E7_uni02E5uni02E9_uni02E7_uni02E9uni02E9_uni02E7_uni02E6uni02E9_uni02E7_uni02E8uni02E9_uni02E7_uni02E7uni02E6_uni02E5uni02E6_uni02E5_uni02E5uni02E6_uni02E5_uni02E9uni02E6_uni02E5_uni02E6uni02E6_uni02E5_uni02E8uni02E6_uni02E5_uni02E7uni02E6_uni02E9uni02E6_uni02E9_uni02E5uni02E6_uni02E9_uni02E9uni02E6_uni02E9_uni02E6uni02E6_uni02E9_uni02E8uni02E6_uni02E9_uni02E7uni02E6_uni02E6_uni02E5uni02E6_uni02E6_uni02E9uni02E6_uni02E6_uni02E8uni02E6_uni02E6_uni02E7uni02E6_uni02E8uni02E6_uni02E8_uni02E5uni02E6_uni02E8_uni02E9uni02E6_uni02E8_uni02E6uni02E6_uni02E8_uni02E8uni02E6_uni02E8_uni02E7uni02E6_uni02E7uni02E6_uni02E7_uni02E5uni02E6_uni02E7_uni02E9uni02E6_uni02E7_uni02E6uni02E6_uni02E7_uni02E8uni02E6_uni02E7_uni02E7uni02E8_uni02E5uni02E8_uni02E5_uni02E5uni02E8_uni02E5_uni02E9uni02E8_uni02E5_uni02E6uni02E8_uni02E5_uni02E8uni02E8_uni02E5_uni02E7uni02E8_uni02E9uni02E8_uni02E9_uni02E5uni02E8_uni02E9_uni02E9uni02E8_uni02E9_uni02E6uni02E8_uni02E9_uni02E8uni02E8_uni02E9_uni02E7uni02E8_uni02E6uni02E8_uni02E6_uni02E5uni02E8_uni02E6_uni02E9uni02E8_uni02E6_uni02E6uni02E8_uni02E6_uni02E8uni02E8_uni02E6_uni02E7uni02E8_uni02E8_uni02E5uni02E8_uni02E8_uni02E9uni02E8_uni02E8_uni02E6uni02E8_uni02E8_uni02E7uni02E8_uni02E7uni02E8_uni02E7_uni02E5uni02E8_uni02E7_uni02E9uni02E8_uni02E7_uni02E6uni02E8_uni02E7_uni02E8uni02E8_uni02E7_uni02E7uni02E7_uni02E5uni02E7_uni02E5_uni02E5uni02E7_uni02E5_uni02E9uni02E7_uni02E5_uni02E6uni02E7_uni02E5_uni02E8uni02E7_uni02E5_uni02E7uni02E7_uni02E9uni02E7_uni02E9_uni02E5uni02E7_uni02E9_uni02E9uni02E7_uni02E9_uni02E6uni02E7_uni02E9_uni02E8uni02E7_uni02E9_uni02E7uni02E7_uni02E6uni02E7_uni02E6_uni02E5uni02E7_uni02E6_uni02E9uni02E7_uni02E6_uni02E6uni02E7_uni02E6_uni02E8uni02E7_uni02E6_uni02E7uni02E7_uni02E8uni02E7_uni02E8_uni02E5uni02E7_uni02E8_uni02E9uni02E7_uni02E8_uni02E6uni02E7_uni02E8_uni02E8uni02E7_uni02E8_uni02E7uni02E7_uni02E7_uni02E5uni02E7_uni02E7_uni02E9uni02E7_uni02E7_uni02E6uni02E7_uni02E7_uni02E8uniAB5B ampersand.scuni2129uni0308uni0307 gravecomb acutecombuni030Buni0302uni030Cuni0306uni030A tildecombuni0304 overlinecmbuni030Duni030Euni030Funi0310uni0311uni0312uni0313uni0314uni0315uni0316uni0317uni0318uni0319uni031Auni031Buni031Cuni031Duni031Euni031Funi0320hookpalatalizedbelowcombhookretroflexbelowcomb dotbelowcombuni0324uni0325uni0326uni0327uni0328uni0329uni032Auni032Buni032Cuni032Duni032Euni032Funi0330uni0331uni0332uni0333uni0334strokeshortoverlaycombstrokelongoverlaycombslashshortoverlaycombslashlongoverlaycombuni0339uni033Auni033Buni033Cuni033Duni033Euni033Funi0340uni0341uni0346uni0347uni0348uni0349uni034Auni034Buni034Cuni034Duni034Euni034Funi0350uni0351uni0352uni0353uni0354uni0355uni0356uni0357uni0358uni0359uni035Auni035Buni035Cuni035Duni035Euni035Funi0360uni0361uni0362acutegraveacute acutemacronuni1DFEuni1DFF brevemacroncombiningconjoiningmacroncombiningmacronlefthalfcombiningmacronrighthalf dottedacute dottedgravedoublecircumflexabovegraveacutegrave gravemacronuni1DD0uni1DC4 macronbreveuni1DC6 ogonekabove snakebelowsuspensionmarkuni1AB0uni1AB1uni1AB2uni1AB3uni1AB4uni1AB5uni1AB6uni1AB7uni1AB8uni1AB9uni1ABAuni1ABBuni1ABCuni1ABDuni1DE7uni1DE8uni1DE9uni1DEAuni1DEBuni1DECuni1DEDuni1DEEuni1DEFuni1DF0uni1DF1uni1DF2uni1DF3uni1DF4uni1DF5uni1DFBuni1DFCuni1DFDuni2DE0uni2DE1uni2DE2uni2DE3uni2DE4uni2DE5uni2DE6uni2DE7uni2DE8uni2DE9uni2DEAuni2DEBuni2DECuni2DEDuni2DEEuni2DEFuni2DF0uni2DF1uni2DF2uni2DF3uni2DF4uni2DF5uni2DF6uni2DF7uni2DF8uni2DF9uni2DFAuni2DFBuni2DFCuni2DFDuni2DFEuni2DFFuniFE00uniFE27uniFE28uniFE29uniFE2AuniFE2BuniFE2CuniFE2Duraboveusabove zigzagbelowuni1ABEdieresiscomb.scdotaccentcomb.sc gravecomb.sc acutecomb.schungarumlautcomb.sccircumflexcomb.sc caroncomb.sc brevecomb.sc ringcomb.sc tildecomb.sc macroncomb.sc ogonekcomb.sc overscore.scuni0342uni0343uni0344uni0345uni0483uni0484uni0485uni0486uni0487uniA66FuniA674uniA675uniA676uniA677uniA678uniA679uniA67AuniA67BuniA67CuniA67DuniA69EuniA69FuniFE2EuniFE2FuniA670uniA671uniA672uni1DDBuni1DDEuni1DDFuni1DE1uni1DE2uni0363uni1DD4uni1DD5uni1DD6uni1DD7uni0368uni0369uni0364uni1DD9flattenedopenaaboveuni1DDAuni036Auni0365uni1DD8uni1DDCuni1DDDuni1DE5uni036Buni1DE0uni0366uni1DCAuni036Cuni1DE3uni1DE4uni036Duni0367uni036Euni036Funi1DE6uni2C7Duni2C70uni2C7Euni2C7FuniA7AEuniAB60uniAB61uniAB62uniAB63uniAB65ogonekcenteringsummationDoubleStruck.miruni20BFuni2E43uni2E44uniA700uniA701uniA702uniA703uniA704uniA705uniA706uniA707uniA708uniA709uniA70AuniA70BuniA70CuniA70DuniA70EuniA70FuniA710uniA711uniA712uniA713uniA714uniA715uniA716xx"-,-xx"-,-{{F-O-xxeeh-h-xxee--xx"-,-``HH)}h-3sh-``HHg-m-, UXEY KQKSZX4(Y`f UX%acc#b!!YC#DC`B-, `f-, d P&Z( CEcEEX!%YR[X!#!X PPX!@Y 8PX!8YY  CEcEad(PX! CEcE 0PX!0Y PX f a PX` PX! ` 6PX!6``YYY% CcRXK PX! CKPX!Kac CcbYYdaY+YY#PXeYY-, E %ad CPX#B#B!!Y`-,#!#! dbB #BEX CEc C`Ec*! C +0%&QX`PaRYX#Y!Y @SX+!@Y#PXeY-,C+C`B-,#B# #Babfc`*-, E Ccb PX@`Yfc`D`-, CEB*!C`B- ,C#DC`B- , E +#C%` E#a d PX!0PX @YY#PXeY%#aDD`- , E +#C%` E#a d$PX@Y#PXeY%#aDD`- , #B EX!#!Y*!- ,EdaD-,` CJPX #BYCJRX #BY-, bfc c#aC` ` #B#-,KTXdDY$ e#x-,KQXKSXdDY!Y$e#x-,CUXCaB+YC%B %B%B# %PXC`%B #a*!#a #a*!C`%B%a*!Y CGCG`b PX@`Yfc Ccb PX@`Yfc`#DC>C`B-,ETX#B E #B #`B `aBB`++"Y-,+-,+-,+-,+-,+-,+-,+-,+-,+-, +-),# bfc`KTX# .]!!Y-*,# bfc`KTX# .q!!Y-+,# bfc&`KTX# .r!!Y-, +ETX#B E #B #`B `aBB`++"Y-,+- ,+-!,+-",+-#,+-$,+-%,+-&,+-',+-(, +-,, <`--, `` C#`C%a`,*!-.,-+-*-/, G Ccb PX@`Yfc`#a8# UX G Ccb PX@`Yfc`#a8!Y-0,ETX EB/*EX0Y"Y-1, +ETX EB/*EX0Y"Y-2, 5`-3, EBEcb PX@`Yfc+ Ccb PX@`Yfc+D>#82*!-4, < G Ccb PX@`Yfc`Ca8-5,.<-6, < G Ccb PX@`Yfc`CaCc8-7,% . G#B%IG#G#a Xb!Y#B6*-8,#B%%G#G#a B C+e.# <8-9,#B%% .G#G#a #B B C+ `PX @QX  &YBB# C #G#G#a#F`Cb PX@`Yfc` + a C`d#CadPXCaC`Y%b PX@`Yfca# &#Fa8#CF%CG#G#a` Cb PX@`Yfc`# +#C`+%a%b PX@`Yfc&a %`d#%`dPX!#!Y# &#Fa8Y-:,#B & .G#G#a#<8-;,#B #B F#G+#a8-<,#B%%G#G#aTX. <#!%%G#G#a %%G#G#a%%I%acc# Xb!Ycb PX@`Yfc`#.# <8#!Y-=,#B C .G#G#a ` `fb PX@`Yfc# <8->,# .F%FCXPRYX +-o,:+?+-p,:+@+-q,:+>+-r,:+?+-s,:+@+-t,;+..+-u,;+>+-v,;+?+-w,;+@+-x,;+>+-y,;+?+-z,;+@+-{,<+..+-|,<+>+-},<+?+-~,<+@+-,<+>+-,<+?+-,<+@+-,=+..+-,=+>+-,=+?+-,=+@+-,=+>+-,=+?+-,=+@+-, EX!#!YB+e$PxEX0Y-KRXYcpB@ z\@,*B@mcSG3!*B@wh[M=**BA %   *BA @@@@@@@@ *D$QX@XdD(QXXDY'QX@cTXDYYYYY@oeUI5# *DdDD ttfautohint version = 1.7 adjust-subglyphs = 0 default-script = latn dw-cleartype-strong-stem-width = 0 fallback-scaling = 0 fallback-script = none fallback-stem-width = 0 gdi-cleartype-strong-stem-width = 1 gray-strong-stem-width = 0 hinting-limit = 200 hinting-range-max = 50 hinting-range-min = 8 hint-composites = 0 ignore-restrictions = 0 increase-x-height = 14 reference = reference-index = 0 symbol = 0 TTFA-info = 1 windows-compatibility = 1 x-height-snapping-exceptions = control-instructions = linphone-desktop-4.2.5/linphone-app/assets/fonts/NotoSans-hinted/NotoSans-Italic.ttf000066400000000000000000016267101376717241300305650ustar00rootroot00000000000000 GDEF,GPOS_ GSUB S zOS/2l6 `TTFAQ+cmap8 s ^cvt \pNfpgm9&|d mgasp glyfx8TLheadJ&6hhea f'0$hmtx'T2loca8Y2maxp& name.Tpost88prepsB*l$=D]wwIUUW##::==?BDGIfknrR]SXYaacdffhh#=AEEIIYn   9ILNOQRUVYY[\^^adffqxz          ( . 0 0 6 6 : H L L Q Q S S [ \ b b l l o t v { }                                        , / 0 2 4 5 5 = ? A B C D E I J J K K N V X _ c c f f i v w w x    ,,4<DN\\d $&/R -   # % ) + , - . / 0 1  7  )F + ,] / 0_ 2 4a 6 <d ? ?k L Ll Q Qm X _n c cv i ow r v~ x z |     @ t y } !CCvvST  "#SS   . 4 7 : ; < > @ C L P V  X  4h = > A K N P R e i /         ! " # $ * + , Y [ n r s t u x y z | }   4nDFLTcyrlgreklatnkernmarkmkmk. u22԰,ؖL bXn $x~x&nnnnnnxxxxxxnnnxxxxxxnxF*d $F F8* * . $ :   nB x BB  B d*n44B"J0L0LBBB"d PP0LfB*B "0LBLRRRRXnnnnnnnnnnnnxxxxxxxx**FFFFFF****dddddddd****8FFddnx~~~~~~~~~~~< <* $%&'()*./2345679:;<=>FYZ\^cm} #%'56789:<>BDFUZ[\^_`bdfgkmnopqrsuv{}<=ADFGMPQSTUV\]ackmruvxz{|}   &(*,.02468:<BCDEFGHIJKLMNOPQ];<CDEFGHIJ}~          79:<#%'579LNP]!"$B A       m       -ZM(((-<7<#%'79LNP]-d79:<#%'579LNP] ; -2"PF mdkqmdkqq~<8Y[^bgnopru =abcdefopqrstuvq[\^dgk  =]v{~;<=>?@ABijklmnwxyz{| (v{;<=>?@ABwxyz{|0 v{};<=>?@ABwxyz{|2v{~ ;<=>?@ABwxyz{| S] SX9 MST[ack|~ "o~oqsoos  STW& dM]ack * dM]ackttMackX* M]ack + dMN]abcdkl XX\^X2W MSack| + MS]ack|;"6;"2,6;< "" "oqsq~brbnorso-K-<                                   <<     ZZ           BFTPY_((222222 22222222(<( PPF<( ((F2j<((d~~~2( $$&'./ 24 7>DEHINNRSUUWWY\^^#mm$}}%&,-.3:AEFKLVWXY\]^_`aefi jpqrs#)t++{--|//}11~335:<<>>BCEGUUY^``dgkkmmoprrtuxy}}==ABDGKKMQSWYY[[ _m ry{~!%124@EFIKMQRXYgioyz!!&>@@BQ]^CJWXgx} !  +-!27}~8:;FPVal |   p p     A;:;$$&&(''..F//'2233U4477288 9:$;;F<<==>>>ADDIIQNN9UU8WW.YZ [[9\\ ^^AmmO}}N( U ((((RF9'''R''  888##2$$.%%2&&.''2((.)) ++ -- // 11 33 55$66 7788 99::><<>>>>BBCCFFUUYYZZ[[ \\]] ^^``WddeeffVggkkmmTooWpp rrVttuu xxyy}}PPX #"/#10"0S/"##=<<  !!<!<"E$ $ $  :;;ON== AABBDD&EEFF%GGKKMMNN6OOMPP!QQ/SS1TTLUU1VVLWWKYYK[[0__``aabb6ccdd6efgghhiijjkkll6mm/rrss ttMuu!vvSwwxx@yyJ{{?||5}},~~05, @E?/" IHIH5,  ?GG   1=1=0"E@J5,,4+4+ 4+4++           &&((**,,..002244&5566&7788&99::&;;<<&==>> @@ BB%CCDD%EEFF%GGHH%IIJJ%KKLLMM NNOO PPQQ ]]2^^. CJWXghin ovwx}     T !!}}Q CBCB7- *  )  3 p p= D D D@ @ J,A,$$&&**224477288 9:$<<==F@@JDDFHIIYJJ+PQRRSSTTUUVVWW*XXYZ \\ ]]:``JmmW}}V]  ++++        ""##2$$*%%2&&*''2((*)) **++ ,,-- ..// 0011 2233 4455$66 7788 99::F;;:<<F==:>>F??:BBCCDD]EEFFGGIIUU8WW7XX6YY5ZZ3[[1\\4]]^^Gdd\ggGkk\pp%uu%vvwwxxyyzz{{}}XXTIT! !/0 # Z/"!#E    . D-C B B.$ $ $  AS@,S@,  ,WV^==%@@AABBDDEEFF GGKK LLMM?NN>OO(RRSS0TTVVZZ[[#\\]]"^^__`` aa?bb>cc?dd>eeff gghh iijj kk?ll>mmnn sstt(uuBwwxx({{||}}~~#(B!C  ZRQRQD!C"-"-POPO "-0E0E0E NN#   #/././."-(DDM M LKLK  !C            !!&&''(())**++,,--..//00112233445566778899::;;<<==>> ??@@ AABB CCDD EEFF GGHH IIJJ KKLLMM NNOO PPQQ ]]2^^*1%;BCD8EJKLMP=QR7SV<WXY^ _`6afghinop5qvw|}~3;1H4 G8 765   I%13 4}}~~Y[  U  ) '  &  9 p p q seD fxm$=D]ww45LIkUUW##::?BDGIfknrR]&S'XYfaahddiffjhhkl{!=AEEIIYn;KQRVX]^_`  b dg9iILNORRUVYY[\^^adffqxz   3  4  8  9 ( ,: . .? 6 6@ ; HA L LO Q QP S SQ [ \R o oT q sU v {X } ^ c e g h j k l m n p s w x             \XHe J>N]6B@\f 6\\Bt],2\\P\\\\\\vN]]]]]dffff 6,666666`|],],],],],\\\\\6\6&HHHH\28J`>DJ2PVe N\N]],]],]],HJbh@2@2j@2nt\\Vf\f\f\f\f\z&  \6`d\H `\Xe Jd\>N]6J\ X   t2"2],X\(0v],e @\*\6Xe ^N\\L>J]6H\*Jr8*6VlT]\\],Z\J]2Be p Jf\>6\R2 Jf"(.4:Xvd6@6@FLR2X^dJjpv||\66d  JrZ NT|$*06^<BH\6\6`&&NT\],\\]],dd***JrZ`flrx~6\RD$\6\6\6\6\6\6\6\6\6]],]],]],]],]],6666f\  \6*] t&\6,\2"8>dDJr*@2JP|V\Jf,b,\,,hxn^tz\6]],f\f\f\f\f\\6\6`t, N\6\6]],]],f\f\TJ\6P]],]],]],]], \He \jjx\ *L e66]"(.4::@FLRXXX^djpppv|\H]]ln42 ]]$*I06<Bd]H6HNTXHBZ`flrx]~\xD]. &,2t8>D.JP V\ b.. h.ntzL@"  ""  ."(..4::@FLRX^djpv|\Pe \JJt $*0>6<NBHNTZ`]],]],]],]],66flflrx@2~@2@2~\\f\f\f\ 6        \\]]]]]]X66H&& &&,28>],],],],],],DJPV\bhntz  ],],""""""""   \\\\fJxXX  Jf""""(R..4:@FLR]e e 6X^djpv|e           \$*0]66<B\NHN@TZD6\`flrxt]~]ttt],\t2\ &\,2>>>>>>>8>>>DDJPV\V\bbbbbbbbbh$eeenetttz eeeeeeeeee]JJJJJ]"Bt(.4:@F^LR]X^\djpv|],\Jf\>\\\ \$ZZ**06<BHNTZ`flrx~ID6E'#B########c#'#p#{,6|6~0DEFPI`pY0@OwDF ?DIG'w'EDA. ''D\FDF&EFEF NEF E DFFIEGOnDbF<`<<<hqDG^z<<QQDQQQ QQQQQQ_#'mJBsBc''rL:|:rY o0(B~nJ@[f3lS:s|[K& fp:pla:xu  w<Wz y I0-<@c+Zup {C[QQmmQQmm388:>EQQC5BHQQmmQm)m88DQ]QQQ mm88Q&Qm,mQzQQmQmsm8g8Q88QQYQQQQ+U>yRoiZ?>B$!/jeiWUB$b?`^kDH0f0DFDFF~F3;CC"~JF]T} ) EEFDBV V1)`;'*%'":dK!H#QVK~''-''l'#b"'Pbb#!#I9x#bf#fj#'nEAA k:E0FFFc%}&BSu'$eBJ1)&HWK( KN'+/27GKORW #$%&XZckoef&'()*+,-./0123]^ Qbz!%)1;@56_`abcdefwxyz{|}~?`NOab + 6 S X>D>,>V>>D>D>D>D>D>V>V>V>V>VX>,>,>,>,>D>V>D>V>D>V>>>D>V>V>D>V>D>V>D>V>D>V>D>V>D>V>D>V>D>V>D>V>D>V>XX>,>D>V>D>V>D>VXX>D>V>D>V>D>V>D>V>D>V>D>V>DF"(.4:@FLRXXXXX>,>,>,>,>D>V>D>V>D>V>D>V>>>>>>V>V>V>V>V>V^djpv|>V>V>>DN>,>V>,>,     >D>V$*006<BHN>,TZe H'+8teee^e`eQeJeeeKeCeIeeezeeeAeeeee  S P(f!e[     AnA6Aee F< Gm$=D]ww45LIkUUW##::==?BDGIfknrR])S*XYiaakddlffmhhno~!=AEEIIYn>NTUY[`abc  e gj9lILNORRUVYY[\^^adffqxz   6  7  ;  < ( ,= . .B 6 6C ; HD L LR Q QS S ST [ \U o sW v {\ } b g i k l n o p q r t w { |              9   ## *3 09z9z$ 9 $$ $2 # 92##$$#$ 9## 8# x:, x 8># ...:::DFFFJ9zvvvPrV"""x\V 444$@@@0bhLLLnIXttt"#t(9$2z##  .4,##&82 $@##x *$ *$ *$ 0 p#RXFL4^d$ ^d  9 89 8 |vt $#Z`r"j(."(. T(.4:@FL  9RvX4<^d9 9z #93 09z#&9 #*jpv|$ Z <r#~xx9H:, b:$,0j$  ##9#0 9h##39z# 9 9j# $$$2 9###r#x#69 # x:, #4Hz$#*:, $0$6<#BH#NTZ`Z`flr"x#9@ ~9$2 $H.4t:#6#*9zIX$:,5#FL 4<3p9h9 9:&t$2,#28>9zH 9 D  JPVP\$ #\#bH hntz#H#6v# # VP HZ9zIX ^"(.4L:@FLR$X#^djp2v|9$2l"(   .4$* $9z906<B<BHNTZFL`"`"flrx$2 $#~ x#9 8##$$#Id9h $ 9p9z $56&,8289 # $ 9hZZ$ >$2DJPV\bhntz":@FLvt $&,9z9 # "(.4:@2FLRX^djpvt|  ~,#   z$9 9 66#Zn# $9 $#$* xH$2$2:,# H$#~##r #$#~ #####IX*$***00#B#B6<<#~<B8#IXH NT:, nZZ`flb$r#6$x~<`:, :,4< IX  &,28> $9z:,D# JH$ $9z# PV\(bhntzHIXIX 6:, "(.4::@FLRX^d j pv|0rxxrlrN` Z$J #IX $* l0r< l66<BHNNrrTxZ`flrx~######   ### $ &,#### *$28 *$ *$>D3 JP 0 0 0 bhV\bhbhntz$ $   9 89 89 8 $# $# $#$ x  "(.  #4:@FL<<<<<<BB99RRRRXX^^^^^^dj4jpNNNNNNTTv|43,,nnxxxxxx~~ 09z;9z;9z  $*06<<<<<<BBHHHHHHNNNNNNTTZ`rfrlrrxxxxxx~~ $99 &,28>DJPV\bbhntz #:,$! "(.4:@@@@FFFFLLLLRRRRXXXX^^^^ddddjjjj#pv|4$#9$$### *9z9z$9h$z 0 # 0   $9   $ * 0 6#~#~ < 9 B H N#~#~#~$ T TIX Z `#~#~ r#~ f#~ l r#~#~:,###$9### x## ~#$ #B ## $2 $ $#98 !!!!!!!! !&!2!,!2!\M!8!>!D!J!PM!V!\!b!h!n!t!z!II!!!!!!!!!!!!!!!!!!!!!!!!!!!!"":""" """"""":"""("."4"4":"L"@"F"L"^"R"X"^"X"^"d"p"p"j"p"p"""v""|"""""""""""""""""""""""##1# #5##0##$9z#*#09 9z#6#<#B#H#N$#TH#Z##`#f##~#l9#r#x#~#################9h#####92$$492$$$$ $ $&$&$,$2$8$8$8$>$D$J$P$V$\3$b$h$n$t$z$$$$3|$$$$$$$$$$^/ls]WXe||+,1- W/C,F&g&&&FLI}{&&&*$zV{>d=cP]@m\<4a'+CgD,T7bKC.vnTA? ~Y @Wyk|G9AzOLf+#>bcH, [L n%sv4du, [%s;4~4},  [%s444rL4M}`sb`?Vem)uj5(D<gDW6W`R k2smQKmD.+Sc^*/.k8"eV!4$|1 5)0P`Y|`6aa a?aaxaMqYYt!9TL j)}@Z"%)6L&cN:{\]C'-O aeaU6aaaaa~aaaa7/7aa}kaaaa3aaaawa!aTaaaaaaaa,c#qevWoHgW!% R#qKW>7GJ}1#X#qR:6GE;I"R/K/$aB<$ho$uch$$_^srVPVVoq_[2zW_H  V,W]qr  ~V|WN{ri(-[jjjy,JuNR r"0!aZ2eaa'2 $#:]zWZQX J,;NsS; 6; _;!J;{"i;?E!B9?2;;k;!mC!! ;;;!+; ;;; !h;e;! ;*;f;Z _!.;7 <! ;a;A!;z !sU;R$;;! ; ;=!18 ;D I!CuEfGGK;?%IQ[aa4chN\&,xt7Uh>n+P5NO~g} (&) *:$=D]4:CINTY_du  &)?HIUUW[^_acefhikkmmoprrtu|}    ?BIIKLww !"#(*+./01"2$3[>AkLQo]^ueewxy|   ++QQSSVXbbzz|}%',..026689;;?BDDFGJP SSXYff9JCJQV_fo=@EEII_`       !#"")..*JL+NO.RR0UV1YY3ad4qx8}@GT\]w    * + 6 6 S S q q } }                      V  b h L * nT  J P t z ^ \  f   f,ff f  T ^ f,,,,,ffff     hf hf hf hf L   ****TfTfTf,,, J J J       f f f f f f t ^ ^   V L nT ^ z ^ , ,   V n L z ff,ff  t t t ^ > n  ff ^   ff,             ,,,,,,, f f ^ ^ ^ \  , f f f f f  hf ,, hfTf  ,, J J f f L  ,,,, ^  f f\\$*06< B  \ \f t HNTZ`fflrx~ > > >       & ff , 2 8 > > D J P V \ V \ V \  b hf L L L L L    **** n n TfTfTfTf,,,, f f J J J J          f f f f f P P t t z z ^           . " . ( . . 4 4,,,,,,  ,,         . " . ( . . 4 : @ F L R X ^ ^ d j p v |   \ \*  P 8T T   *T ,fff  ff f f  ff    $ $ $ $ $ $ $ $ $ $ $ * 0 0 0 0 0 0 6 6 < < < < < < < < < < B H H H N N T T Z Z Z Z Z Z ` f f f f f r r r r r r r r r r r l r x x x x ~ ~ ~ ~ ~ ~ t  ,f \         & , 2 8\ > D J P V \ b hSyPa#afaaTP DG 8`1:aaaaNJ{}a{aa~k.#ta\ana(Z^xzceRg@D50HpCU(RX[DMMZD^;;;N;;;\;;;;;y;;z; ;;;X;;;;;;@\piWo ]hmhhF\+ 8usTP $6HZZttV    $C  DE Z g"(.4>[$*06<E$E$q  .  T c*Q - : l tB$T6BTf      e ee S  "(.4((_/(|/#/#  2cQ - 0 : b l t f $6HZZttV  Z# xZ]b T$$ l   B"(.4x+H$*06<L>LD 9x Jefc*Q - : l t f<NZfr~n 2>Pbn HR +: 0T  h } %  }_ * h B;0;  X"(.4Zw,$*06<^*^D  @X   # % ) + , - . / 0 1  7  8 6 <: ? ?A L LB Q QC D     " $ ( * + , - . / 0  6  )E + ,Z / 0\ 2 4^ ? ?a Q Qb X _c c ck i ol r vs x zx | { E"(L.4:@F^LRX^jddjpv|  h3" &,28>DJPV\bhntz "(.4::@FLRX^djpv|44&&00QQ#4O98GFHcf"$&O"4%!Sp% , Mlfl GG7"[l$C ZlLlWl2 Vl1 KlJlQlT*lIl]lElFlHlNl  2p @    t y }  &,28&"^ |`  "CCvvST  "#SS   . 4 7 : ; < > @ C L P V  X  4h = > A K N P R e i #"# & ) , - . 0 2 5 6 ; ? E  G  ,W / 0o 2 4q = >t A Kv N P R U X _ c c i o r z | 6<BHNTZ`flrx~ J882\(DDt(P &D\,((28>DJPV\bhntz((((((((((((((((((((((((((((((((((((((((((((((( (((((((( (((((((((((((((("((((((((((((((((((M<WaPgVp_j`/:A^'LBqm<6=A2SOJiL4;(?0>E7|H)518$G;;Y;5;2;`;F;K;j;[;H;3K _3E>/G8F9`flrx~ &,28>DJPV\bhntz** ****"****$****(****.4:@FLRX^djpv|********* *$*=4krVl=L[\Inbc/LsJV^gKNHI__b*\\fiVXf&\K`+atn\XPZk\#c#J\P^dT gK]/Y1aHjybC~B4o_Ba`1_8d@ x clk}F}XR\wF3.0;vB{BBBfxBH[B}BtBBwBssBuB|B  j        $ * , Y Y [ [ n n r u x z | }  %$KjY+X^djv|pvv||  BBBB B7BBBBsBBBB "DFLTcyrlFgreklatn  SRB 2  "CAT JMAH tMOL ~NAV ROM       aaltc2sccaseccmpccmpccmpccmpccmpdnomfracliga lnumlocllocllocl"locl(locl.locl4numr:onum@ordnFpnumLrtlmRsmcpXsubs^supsdtnumj "#     $!%L`~llN > > ` $ J J b * j *D   5 `N  & ) , 0 3 7 Q Q9     ! " # N P$ n n' s u( y z+  - . / 0$')( 9012345678LM%g|K^0:DNj|",6@JT    LD   F 3     LE   G 4 :BJRZbjrz                            :BJRZbjrz - / 1 0 . 8 ; : 9 C E G F D = ? A @ > 3 5 7 6 4 , B < 2:BJRZbjrz e g i h f q s u t r | ~  } w y { z x k m o n l d p v j:BJRZbjrz I K M L J U W Y X V _ a c b ` Z \ ] [ O Q S R P H T ^ N:BJRZbjrz           ' ) + * ( ! # % $ "       & $ &  L L L L$(,28DHLRX#% n&0:DNX        $.8BLV`jt~            $.8BLV`jt~            {  }~34HI#$ ]^ >(>JJyOy/y n o p q r s2 0 1 2 3 4 5 6 7 8 9   KNOPQSVW$ :{tu'(;)*<   Q   "B*    $ $,$D2Rl|l|$2DR .        .      .           :     M          A B C D E F G H I J K L "$%&'()*+,-./0123456789:;<=>@^`cq  !#%')+-/13579:<>BDFH] 8     M          A B C D E F G H I J K L ">@DEFGHIJKLMNOPQRSTUVWXYZ[\]^`cq   "$&(*,.02468;=?CEGI^ B    6 "(ILIOILOI %XKXJ^2B  @)GOOG--%  J ~01ac67Y] AEbw~  OP\_'/=?EMWY[]} d q  !_!!,m,-.Ds}!.Ze/ 12bd78Z^ BFcz PQ]`(>@ HPY[]_ f t !!!,`,n-.@t~".0[  HJHP ~GtI=EvZ;9753210/-,+)(&%+Mc5ee`Y`baa^58<.>D<RfjHhTHI#$&'#$JKLMNOPQR  n u z s t y  y ~ z  { |<=>L R S T U Vpqrstuvw  <  =  >  ? ? = > w o p q r { v x i | } j k l m ~    AB+,!LMNOPQ*{|$%&' ()*   ^  R +,-./0 1 ? i 2 A @ : S = > b c K } k ; < ] m B x V N y Q M P E 3 456789: '(;)*<  BCDEFGH R R   T  x  UV - . /WX ' ( ) * + , !" % hijklmn"/-. o n Z s W p g f H [ t h Y r J a O j T F I Go U ` | X q z { \ u _ w L l v e d C D ~  I  J  K  L  M  N  O  P  Q R ! S " T # U $ V % W & X ' Y ( Z ) [ * \ + ] , ^ - _ t W f g h u . ` / a 0 b 1 c 2 d 3 e 4 f 5 g 6 h 7 i 8 j 9 k : l ; m v w b c:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ [\]^_` abcdefghijklmno{|}~p qr  s t u v w xy z  6 7 8 9 : ; < d e^*@'eU]M+3!%!!^563d/@,~oK_xL  +73"54632M[kK5$'$6 14m$@!]oL +3#3#`K#`KG@Df   eoK  p L +37#737#73733733#3##7#37#a;~0D</3232>54&#""&54>32'2>54&#"7< +B.9< -AN '&7< ,A.:< ,B&'&JGNRG+GBOUJ.6V'=B:)%$8A<PJFORF+GAOUK.B'=C9)%$8A<P !-8{@21JKPX@$_wK_xK_xL@!_wK]pK_xLY@/..8/8*( !! +"&5467&&5466326673#'>54&#"267'Qgb\-V=IV5Y4!.XF,ch7/kC.(&175P&%?(@ [WPh, K*3Q0MB2H8L(>e*N&2'4##,:3;Y+,=,3<m@]oL +3m#`K(bo@oL +&&5473p"&vQGn>=SzNtW>b@oL +>54&'3MGm>D"%wNtV>>Syg,3@ H Gt +''7'777't6{=W;W,å=5NY RFoS &@#Ue]M +3##5#5353UHHGGt@t +6673+6`H#;4 5~74@U]M +773QQy @_xL   +"54632H4%($4!23@oKpL +#3.Zt69#-@*_wK_xL##  +"&54>32'2>54&#"X[+FcA\X-Fb5(?/ /0&@1"0 ~u;j@woHe:K4Ypy:JO3Wlu6QW !@ JoKpL  +3667'73_   X)M.a 7B6,@) J_wK]pL'%( +377>54&#"'6632!BT(73,J#*)d@[a,dRFK@I#D/.1 >(XFLj P@8e? .@+JfoKpL  +!7!733#%37>7# #ecno#$P&N%QH $" % D@AJg]oK_xL    +"'5326654&#"'!#6632aB$S,FV'H>4 %aI<*YiAo 'U0O.=E PPeX-[L.?"0G@D  Jg_wK_xL '%0 0  +"&546676632&&#"36632'26654&#"Th D5+vM6&)_#T4JX=^71D$45$<*0 kpE4,0 L&-^V2cQ1J8Z38= .($?(Q2@]oKpL +3!7!Qu |NF|-(65@20J_wK_xL*))6*6$"  +"&&5467&&5466326654&#"26654&'EY+dY&/8a;AQ$/L,4=3lDG6.5A,2@34-I*B 1Q1Mh"F7;T--H)5I3 RA5]9C5+2=5-:%; 0G(?/4;/ .G@D Jg_wK_xL! )' .!.  +"&'53267##"&546632267654&#"?:#dwO0SY7>54&#"'6632"54632/$ 7"0.&I! )b/O^IF'+E4%(%+@6.8&,0CNOCd4(,#4!2356@N@" E =>JKPX@( g c_oK _r L@&  g g c_oLY@BAIGANBN;931*(  @@ +"&&54>32#"&'##"&54663232>54&&#"32672677&&#"eR@zlj?7a=8-D28AEsD0@/2#/jYVd66l,4p<0?! /K, [Pj[MSOYP6#%4HDQ{D '*EU+BlA=mSAUC|6\9,(,@) JfoKpL  +#3#'#3'&&'#9^XXt*6.&\#&W,)M#9@6Je]oK]pL#!! +332#326654&##32654&##)cqXI1BG|O4u,J,JpNVI[ H32&&#"3267Fw=]|NdJ$C,KmH#]R)O&'O @v]6(JCoC[i N)| '@$]oK]pL ! +332#'326654&##)aGLhJiWUʌ|oM^dna)* /@,e]oK]pL  +3!!3!!)j/7ONO)* )@&e]oKpL  +3!!!!)j5@OOH!>@;  Je_wK_xL !! +"&54>32&&#"32677#73W7gVAb,"&U3RL'R@&?.L-d bGNbo7Y4 N* '@$foKpL  +33!3#!*Y@:@XXFF.6M} "@ JoKpL  +#77'73 UzL VzM 1@221dB(@%JcoL  +"'732673P2$,D Ym M7A5eX) %@" JoKpL  +3373#)YJ>lʩbS<BpZ=)@oK^pL +33!)YP(L'@$ JoKpL +3333#667###(~E=ZZ GL [G6Aj rCK#S($@! JoKpL +3336673##(_ TU_ R$o26PDO$|H-@*_wK_xL  +"&54>32'2>54&#"Q1^Ty-YT<^B#ZN<`D$\ \I]}HO`qCDLgSybRY;5HV$8@5J_wK_xL$$&# +'"#"&54>32'2>54&#"l1^Ty:pO=_A"ZN<`D$\\IgNNd[ECLʵMr'sWE=0*7@4J_wK_xL** +"&'5326654&'.546632&&#"4O#S6-L.5A&;!@k@8U&"N)>N."+A% X:.(9%2@/B]0L@:("2B1knZM!@]oKpL +3#7!#ć{OOO$@!oK`xL +"&5467332673,pm\Y]EDYVcYdEt g_1L28@\Y)Nr=\ !@JoKpL  +3336673MX-&c<)T$$O/6k!'@$JoKpL!! +333667336673#&&5#X([ _[ M)X('e,^/f%&Z,6!K?17a &@# JoKpL  +#33#4#Zab^fzP5\Y"@JoKpL +333:tYUe7 f?= %@"]oK]pL  +#7!7!!  COF4PGPbr"@a]oL +3#3 nnhH(Hl&@oKpL +33jPj6b2"@a]oL +73#73HnnHH& 'dD@Jt +D3#&2N <gb@&dD@U]M +D7!\DD^6 &dD@ Jt  +D.'53+& ^ '^68 %M" 0&"&g JKPX@_zK_xL@!rK_zKpK_xLY@ &&  +"&54>32373#7#'26676654&#"AP'F`:5B CrF #[$H94,'B2, ]ZKg<8%Sc,AI6[:2/<1Ul;66'JKPX@qK_zK`xLK)PX@!qK_zKpK`xL@!_zKpK`xLYY@!'' +"&'##336632'2>54#" 6C!BX& $U8BQ$D`D(B/U!E:#2 7%R"B*,A\ZIi=I3Vl8l1Ul;0<0"7@4  J_zK_xL  +"&54>32&&#"3267Yn'Ih@#E7 9V0>8#?E ddHb9 I ML=CJ0U& JKPX@qK_zK_xLK)PX@!qK_zKpK_xL@!_zKpK_xLYY@!&&  +"&54>32366773#7#'2>54&#"AP$Ea=6A %WH $V!D:#/5(A0 \[Ii<7%">$c-@I1Tl<0<3Vl8l0"'>@;Jg_zK_xL&$  +"&54>32##3267326654&#"]e%Fc>LMAn;>&D(&I#%0Y m]@}g>B;5U3 =GK91)!Y$w@JKPX@!_qK]rK_tL@g]rK_tLY@!  $$ +"&'53267#?>32&&#"3#0 $( n]d 0F14"'. s spLJ;7 %!0EM C ,>3CS^'"$3@JKPX@"_zK_xK_tL@&rK_zK_xK_tLY@&%.,%3&3! $$ +"&'532677>1##"&54>323732>54&#"1SY+>O  #V8AQ$Ea=6A!Cz{;"D9"-5(B0Q32#654&#"X+4C+>IFXG !%"OC1A 2"ED(P-!%/jX MK-PX@_wKrKpL@grKpLY@       +"&546323.$rXrq&-#  e@  JK-PX@_wKrK_tL@grK_tLY@      +"&54632"'53273-$% =WIq&-# Jb]KX G JK)PX@qKrKpL@rKpLY@  +3333#'YAhaqH(PW90K)PX@ qKpL@ pLY@  +33X3"0V JKPX@_rKpL@rK_zKpLY@00%&&% +333>323>32#6654&#"#654&#"rH 1@)7<7D)>DEYH!#!H?3XG # J@1c2"@77#D@*P!$0fPP-!%/jX%LJKPX@_rKpL@rK_zKpLY@ %$ +3>32#6654#"sN 4C,@JG^HD"MC2c3"G@0T@/hX0-@*_zK_xL  +"&54>32'26654&&#"]k"CeB^j"Cd>/O/0(7Q,=o_>zd=o`=zd=IC~X9%K}K>D!&hJKPX@_rK_xKtL@!rK_zK_xKtLY@ &&&$ +336632#"&'#2>54#"H #X8AP$Da<6B1(B/U!E:#2d,A\[Ji<7%9/3Vl8l1Tl<0<0&"'gJKPX@_zK_xKtL@!rK_zK_xKtLY@" ''&( +7>1##"&54>323732>54&#"*0 #V8AQ$Eb=5A!B!D9#.4(B05),A\[Ii=8%S/2Ul:,@3Vl8l"cKPX@ J H@  JYKPX@_rKpL@rK_zKpLY@ $% +333>32&#"rH .:& 2N4 4c2 OBf5"&7@4J_zK_xL&& +"&'532654&'&&54632&&#"1IP*;>&49:cS1S@,,2#5"6q Q.&' D3DTF ) '(5%QT,lf@ JK PX@n]rK_xL@]rK_xLY@  +"&547#?33#32676J =SZ>4>" 2 4A '#(&ozC ! C 7&PJKPX@rK`xL@rKpK`xLY@  +"&546733266773#7#=IFYH &"NE1WrH 3D DA(G+ %0jXc2"0!@JrKpL +333>73n>X  ^F=@@'9"'@$JrKpL"" +333>7336673#&65#OV _ (u]j 7Y99/%a&&g7"(J/%?3 &@# JrKpL  +#373#'%tYSf{Y[0@- JrK_tL  +"&'53267733>73 (:#QX# ^)XG20> !LE@D&KK %@"]rK]pL  +#7#7!3 ME <BGqB b,7@4Jgc_oL+* ,, +"&546776654#726776633"3GJf:F !SS,3 # ::'$)"59!i FI*3O?I/3B  6' "f  IL0K)PX@ qKtL@ tLY@  +3HbY-1@.Jgc_oL-,&%$# +526776675&&546776654˜3"#%07 # 9;'#.)HKf:E ! .J8I/3A  5'!g  I59!j FI*38>F<dD@1JHGWg_O$$$" +D&&#"56323267#"&!$/>0H:.$/>1G:? "N5  "M6 J" /@,~_zL       +"5463234%'#܆:U4!24k  e@ JK1PX@g]oKpL@gW_OY@ %& +7&&5466773&&#"3267=I.>!?/>55?0?>2FF21DD>>/>49/?0??/?65>2D12EE21D<h>@; Jf  eoK  p L +37#737#73333#3#mcVT`oCMCwfCMCLLK)PX@]qK]tL@e]tLY@ +33HHH{}}2>[@9-JKPX@_qK_pL@g_pLY@!22 +"&'532654&'&&5467&&54632&&#"6654&'2IP)?C+68BD. a\/P!@"0+55E?1 k33=:3 K+(%A89G0#:S? #?63O,"FY:&- 7("-w 3dD@(W_O      +D"&54632#"&54632 w""1&?edD@Z0<1=Jgg g W _O(':842/-'?(?&&  +D".54>32'2>54.#"7"&546632&#"3267Pc66cPLe96cP@pV0.SqDZP.SrScb.ZAA:2+;A9B92 6cPPc66cPPc65.UrEArV1Q[ArV1Z{eAe9=UIMR @ R"K&PX@ J@ JYK%PX@c_LK&PX@gW_O@+~~gW_OYY@"" +"&546632373#7#'2>54&#"%3%G5$-E/0) /979hB,8$5#5;"2N(" *6  0+7'57'57p+Ri/L6 +&F%@"U]M +#5!5GqG41&4=idD@^/J ~g  ge W _ O''=;75'4'43210*(&&  +D".54>32'2>54.#"'32#'#532654&##Pc66cPLe96cP@pV0.SqDZP.SrERL0tVd>2',(,1 6cPPc66cPPc65.UrEArV1Q[ArV1_A@/7 ­' # e;&dD@U]M +D7!eCC7u 9dD@.gW_O      +D"&54632'2654&#"HWUJFYYE0-/.1..UDDVVDDU;4*,44,*4FV 1@.ee]pL   +3##5#53535!UHHGGGGGU2@/  JgU]M$' +776654&#"'66323G <8/0C()36.h 7n4D''//!8<&W=QV'M@J!JggW_O '' +"&'532654##732654'6632!;>21T. ..8@-D*<<60"&S A,%@7&#;0:+-7 1":Ns^G &dD@Jt  +D5>73s*&d7>^ 46 99, _MYJK)PX@~]qL@~U]MY@ &" +#"&&54663!##s)>\37cB:f .l[_n.)Q=+ +3+i:dD@/ JW`P  +D"'53254&'73( R%08)K45X9!%-=`K @ Jt  +7667'735 4>[? "/\TVs PK%PX@c_L@gW_OY@  +"&546632'26654&#"4F%I7?9"G5!-##.$AB4_=H84`?4-H')%+F(() 6  0+7'7'7'7'7+R=p/L=i6+%V'F'{'/a3+a3+X'H'{tla3+a3+7'u~''l`~3+`3+?d!" 3+&$C3+&&$v3+&$Jp3+I&$Qm3+&$j-3+&$O3+`?@<ee ]oK] pL +#!!!!!!7#3#:06/֋G)ONO.MHx&&z)*&(C3+)*&(v3+)*&(Jj3+)*&(j'3+}&,C3+&,vh3+&,J3+&,j3+!| 7@4e]oK]pL ! +3#7332#'326654&##3#)AIIEaGLhJiWU4;MB|oM^dnaM(&1Q3+H&2C3+H&2v/3+H&2J3+H&2Q3+H&2j}3+T> 0+''7'72244>33349$0=@: .-J H_wK_xL&%%0&0%+) +'7&&54>327#"'7&&#"2>54&'r9B1^T]C?:H-YW`A a7#<`E$<_B#9).R#\5\I4O.X[4]}H.;hN==S_0&&DCg0&&Dv0&&DJM0&&DQJ0&&Dj 0&/&DOt0"0;MKPX@  -*#$J@  -*#$JYKPX@%h  _zK _ xL@-hrK  _zKpK _ xLY@#=<GE323736632##3267#"&'#7#326654&#"26676654&#":G'E]60:!8Q65P@n@; J Hg_xL$#-+#2$2"" +"&54663276&''7&&'77'2>54&&#"Yg?rN:D+r#/1~ s#-BnL2D)3*geW_O      +"&546325!"&546321!! !!  "" GG "" <"-=@: +*J H_zK_xL$##-$-%+( +'7&54>327#"'7&&#"26654&'R56""CdBI1158!BdBE2 "7S-w/Q0 '&)C2N>zd= =(>D">|g?x2 KzF*cBzT 7&&XCm7&&Xv7&&XJS7&&Xj&\vw*lJK)PX@!qK_zK`xKtL@!_zK`xKtLY@#!**&' +336632#"&'#2>54#"X& $V8BP$C`=6D1(B/U#J< 1+J,A]ZIi=7%:/3Vl8l7_<.-0<&\jW&$L3+0&&DLi'&$M}3+0&&DMZ'&$Pm0'&"&DP1Hx&&v#3+0&FvHx&&J3+0&FJ*Hx&&N"3+0&FNH&&K3+0&FK.)|&'K3+0&G%d!|0.  JKPX@'fqK _zK _ xLK)PX@+fqK _zKpK _ xL@+f _zKpK _ xLYY@! )' .!.  +"&54>3236677#73733##7#'2>54&#"AP$C`=7C WIIH $V!D:#14(B/ \[Ii=7$132##32673267#"&5467326654&#"]e%Fc>LMAn;>&D()C!  &34(r#%0Y m]@}g>B;5U3 =GK!G&!7')+=91)!Y)5&(Kn3+0&HK6H&*J3+'&JJIH&*M3+'&JMVH&*N63+'&JNH#&* '&J&9*&+J3+ &KJ3+);@8  f  eoK pL +3#7373!733##!!7!)n[[Y:Z[]nZFFW: HxxxxHMn %h JK)PX@!fqK_rK pL@!f_rK pLY@%%%' +3#73733#3>32#654&#"KIX4C+?HDXF "%"OE.\BZZB9]3"GD(G+"'0kW&,Q3+&'QW&,L3+Z&'L&,M3+i&'M'}&,P9'&LP }&,Ng3+B^&,-D&LMdB&-J3+[&)J)#&. B# &N ' %@" JrKpL +3333#'qYhaqH(%D9)&/vc3+&OvN3+)#&/ (#&O )&/%o а3+&O%)&/N 3+_&ONv Ű3+  *@' JoK^pL  +37'737!(54dQZFp/:9?8\P% =@ JK)PX@ qKpL@ pLY@  +3'737=7fTXF:hJ!7>"7>(&1v-3+&Qv(#&1 s#%&Q 5(&1K3+ &QKY)\&QN(C<@9 J IcoKpL +"&'73267##336673^+ $+D  RT_ PVnM2<P&o7|*q5w6eX "'m@JKPX@_rKpK_tL@ rK_zKpK_tLY@'' +"&'53276654&#"#33>32 <V"%"ND1XrH 3C+>IVIJc!$/jXc2"D@+lJXHW&2L3+0&RLVH&2M3+0&RMGH&2R3+0L&RRfH$IKPX@#e _wK _ xLKPX@+e _wK]oK _ xL@3e _wK]oK]pK _ xLYY@$$  +"&54>32!!!!!!'27&#"Q1^TH+_06'"v'5<`D$\ \I ONOO - ;gN_i0D"(3AT@Q & Jg _zK _ xL54<:4A5A20+)$" (( +"&54>326632##3267#"&'326654&#"26654&#"Yj"DgDIP$d;AR?n<=%D((M,?Y` 8^:P)687Q,;o_>zd==.4:=@5U3 =GM64/971+!UJP8DK{HBE)9&5v3+&Uv)#9&5 D#"&U )A&5Kz3+&UK&6v3+&Vvm&6JJ3+&VJ&6z"&Vz&6KN3+&VKW#M&7 '#l&W ZM&7KV3+,&W%#SM/@,e]oKpL +3#737#7!#3#E33EGIOOIl%@ " # JK PX@'n e]rK _ xL@& e]rK _ xLY@  %% +"&54677#737#?33#3#32676JCCSZ>4v w" 2 4A$hBy(&ozCyBi ! C O&8Q3+7,&XQPOW&8L3+7&&XLoO&8M3+7&&XM`O&8O3+7&/&XOzO&8R3+7e&XRO'&8P7'&&XP1k&:J3+9&ZJ\Y&<JV3+&\J\Y&<j3+=&=v3+&]v=&=N3+&]N~=&=Ke3+&]KX@JKPX@_qK_tL@g_tLY@ +"&'53267>32&&#"@ - /G16"(. LJ8:EM C ,>vS^!#I@FJe_wK_tL  ## +"&'53267#?6632&&#"3#? . b\d YJ5!(. s tcKJ8:$!EeM C ,>HB)S^- (2\@Y J g   ee pL /.*)$"((    +56673&54632#'#2654&#"3'&&'#Q=n 8?8U@,0>LWuJ  #= E -.w+1871-&J I'0& "7I@ 4. JKPX@6 g g _zK _ xL@> g grK _zK pK _xLY@.98$# CA8I9I3210,*#7$7""    +56673"&54632'2654&#""&54>32373#7#'26676654&#"C>n 8@1<@-.>>. AP'F`:5B CrF #[$H94,'B2,> D --712762271|]ZKg<8%Sc,AI6[:2/<1Ul;66`&vb3+0&v:9&v63+&v#&6 #"&V s^)dD@ Jt +D5>73#&&'s85U27)=^ 59'O 0/^)dD@ Jt +D&&'53667315(>986^&P 0/ 59p^&dD@U]M +D7!p ^GG^2dD@'HW_O  +D"&54473326736F4$,..7T^97  !H>q 'dD@W_O   +D"&54632.$q&-#^b/ 9dD@.gW_O      +D"&54632'2654&#"0<@,0=>/ ^721761372'z8dD@-JW_O  +D"&546733267.&3;-=+!  ')/>&.!7p^4dD@)Wg_O"""" +D663232673#"&&#"p:+2* 5:+/+ ^>B>Bs^ ;dD@0 JU]M    +D5>73#5>73)'Z6>*'Z 7?^ 46 99 46 99-^& &dD@Jt +D5>73-  ^ *4^CDCIwF !dD@ JK PX@$n~W`P@#~W`PY@ !!    +D56673"&546323"&54632,bH&z   T$ S#/""&$S 3+Q=+ +3+0&(_S 3+&&+MS 3+&',S 3+&&27S 3+'<S 3+0'SE 3+3yF&T$)M%)*;K1PX@]5K6L@]5LY@ +3!!)jO)*(==*+H#>@;e_=K_6L  # #"!  +"&54>32'2>54&#"7!R2^Ty.YT=_B"ZO=`C$\ ]H]}GO=jJ_j;hM^kMM},). :JK1PX@ 5K6L@ 5LY@ +#3#&&'9_YX5*7)Y%&V0A(L0(1* eK1PX@ e]5K]6L@ea]5LY@   +7!7!7!]:B{OONNOOH2)>K1PX@]5K6L@]5LY@ +3!#!)ZƆ6{)733 KJK1PX@]5K]6L@a]5LY@ +#77!!!`I(GOOZM7\Y<H$tJK1PX@#hW5K ] 6L@#hW ] 6LY@$# +7&&5466773'>54&'iuDx[gv#N^4RQd/MOe0IJ nrgSUXXqe7m[:n?h=GQBg>APa;`"NK1PX@h5K6L@h5LY@""$!! +!7#"&&547733333266773##.Q_( )],ZZYDV0 2]3Fd.9Z2-7*}\.S7HrB&,j3+\Y&<j3+0;&&{S&&S &&S3N&&Sm@F&T70;"%7m@ " JKPX@_@K_6L@8K_@K_6LY@'&1/&7'7! %% +"&54>3236673327#"5#'26676654&#"@Q&E_99@H  #$Z"R$E73,'B0, \[Lg;6&1JZ, $@c):I5Z:4/<1Tl;766-L@I +Jg_?K_6K:L'%!--*$ +>32#"&'26654&##732654&#"4aPU`4I8kM:F=6H#@N #XN1309 [G?h?YP& OKEm?#.0K*{=%^)+a=}D#, .9@6(J_?K_6L"!!.".  +"&&5467&&54632&&#"'26654&'BX-s"4aS:X#G+1..(4H;uM3J'*:a:< 4W4qH2CW%? .%&2 *iOI}MI6[8;I9[@=E!+J@G()Jg_@K_6L&$ +++"&54675&&546632&&#"33#"3267YYV=,:[13K @%2F.1=9)D)08.S"\ N32.{"%"ND1XrH 3C+>Iz@!$/jXc2"D@/0&9@6e_?K_6L! && +"&5467>32!6654#"267!PT MqOIY Np}UC[DX"+ fh,b.xZbu%b8q["E)I!JC3+@(J8K`6L+"&5467332674GKXL  3 4A%d  C  %KPX@" #J@" #JYKPX@_?K_6LK1PX@_?K6K_6L@~_?K_6LYY@ %%+"&''&&5#'&&#"'66323267*-]0 & &L= 9 ! -: P&"? F,6FLM B0:JK1PX@ 8K6L@ ]8LY@ +336673rBX#_kWItW(L%YnL(65{K&PX@  J@ JIYK&PX@g]7L@ pg]7LY@55(&%#+6654&'&&54675&&54667##7!#"33#",.//DBje.;+I-, /+WH,DL.&;lD/;7#4'9 QDQv =3)B. JD';'16D%M<.4 2$.E0R&vKPX@ J@ JYKPX@]8K_6LK1PX@]8K6K_6L@ ~]8K_6LYY@ +"&547###77!#3267.1 AdYdm`hB $ 0(/:3$'K D !#<@9!J_@K_6K:L##&$+>32#"&'2>54&#"u 4`N\c>aC1E ,B,38BC'<+;jAmf9xg@"'E*/1Q_/?J`P 00"&)@&J_@L&&%.+6654&'.54>32&&#"-.!4"B+#GiF%B8"/G/1%5 2"(@.RAguZWJL@/i\9IFrC/JDqCNG&5@2J]8K_6L +"&5467#77!#32676J8_;9" 3 4A2$'K( C @$@!8K`6L+"&5467332>53Y` 7X7 8/.A+ X #@g ]S-**-941Rfkb$GqC0w!)7@4 J_@K6K:L'%+7.54676632>54&#"14R0SQ8DA2APNHI"JxW0A'E2@/J7K8K6K:L+7&&5467733>532c[5X53AV^e&ZJf1 eO0-5EK z̆tT0.:@7,J~8K`6L*(  ..+"&5467332677332>54'3#"&'EFB=\5M((4 V=)9$ W!8S9.: E dQYXQa>0D?$ O>an0WE$Q$+iiW50'+,3\&jo@&j 0&&RS@&&S0&&SY)*&(j'3+ZZ#KPX@ J@ JYKPX@ e]#K_+L@$e]#K$K_+LY@## +"&'5326776654####7!#32& $2/ dLY*}[ZZ N 74$"Q{OONI1%ZT)*&`v3+Hx#F@C   !Je_*K_+L ##+"&&54>32&&#"!!3267FTq9=]|NdJ$C,HlH,[T)O&(P D{R@v]6(J?j?O$]f N6},&,j3+dB-E&.KPX@ JKPX@ JI@ JIYYKPX@ g]#K_+LKPX@*g]#K]$K_+L@(g]#K]$K_+LYY@.,)'&& +"&'532667>7!32###%3254&## -)%&%M?3T^'HS "!4LHB;C NA<.x<0P0Rh2z1uyo+?\1W;0)O3@0h#K] $L&! +33!332##!%3254&##)Y@@Y@5S^'HRFFyHB;C-0Q0Rh2NL;/ZZ-@*e]#K$L$!+3#7!#32#7654##r*ZU*Z- eL{OONL*'"Q)&v3+&$*3+)D )@&#K]$L +7#3!3#)͗Z;Y'{6$**1@.e]#K]$L !+3!!32#'3254&##*i/FS_'HSMZB;VO0P1Qh2L;0)M%)*`En3@0Q]#K]$L +3>7!3#7!!#T83-]UC#[9U'K(}vx=KQ >I )8)*(j,@) J#K$L+#333##2K`HVH3jcKVKxRTTdd +J@G$Je_*K_+L +++"'5326654&##7326654&#"'6632rO$k7BS(RKf_1Y:<2-W)$3kEVbcU8I@710 @""WHLg NF7#)UThTT:wLEI6"KC)&$p3+) %@" J#K$L +333#)YJQlfJ[bqKPX@ J@ JIYKPX@]#K_+L@]#K$K_+LY@+"&'532667>7!## -)%&%cZ "!4L NA<.x<6z1uyo+?\1(L0*+H2)l)73Hx&ZM70@- J#K`+L +"&'5326736673S.*6K+ZV  e+MS W ?F#C!9MES$Hqa;(E )@&R#K^$L +7!3!33(#Z,ZS:zw+@(Jh#K$L&#+!#"&54677332673>"d;KQ5Y4(02a(HZ#GB$! %'\6( %@"#K^$L +333333(ZZYzz6(E-@*R#K^$L +7!333333'ZZYS9zzZ=1@.e]#K]$L !+3#7332#'3254&##s@AT^'HSGTB;Q{O0P1Qh2L;0) 6@3f#K]$L    ! +3332#!3%3254&##)Y@@S_'HSUY SB;P0P1Qh26L;0) +@(f#K]$L !+3332#'3254&##)Y@AT^'HSGTB;Q0P1Qh2L;0 , F@CJe_*K_+L   +"'53267!7!4654&#"'6632_K)O7t'ST/L"%`8t(X 'VyO Sj JYN))KPX@!f_#K _+LKPX@%f#K_*K _+L@)f#K_*K$K _+LYY@" ))  +"&&547##33>32'2>54&#"a[q3FYY@\Yp,UP=\<VJ9[A"!H L~K!!ZR]~GO@mFbf;gN7[6B8@5Je]#K$L'+#&&546633##3#"'(6JzIZ?lG9W2P/BFJ@Sd-6(t ?66C0&"D1C!35@2JHg_+L#"+)"3#3!!+"&54>7>76632'2>54&#"\c%;U9ERJ XY@[\;LK=a<,<%**%C52 so-u{pR H x_ :_U=u^8I1MU#<8$16CS0!*?@< Je_,K_+L! '% *!*+"&546632326654&#"2654&##neCZV^L;+9)`m,M/*1G`cB=>C~E xe^YEC;B  34%M39+$*X8&&&ME!)7@4&'J_,K_+L$" ))+"&&546676654&#"'66323267.O06R+3236454&#"'6632'2667&&#"WZ ?]=;@BD:N$nf/Hd72L4 <.-M.- kX9ta:3"{v A ={c:JLzF0AFuH4F0"Hi"JKPX@()7 8J@()7 8 JYKPX@&   f_,K _ +L@.   f%K_,K $K _ +LY@#FEDCBA<:53-+&$  JJ+"&'732>54&#"566323733>32&&#"3267#"&5447##7#,! +C.,4$VVR1Q2O &=W9"  +B,*4 $VVS2P3O )?W H2Qa/:LHma (UH-G2Qa.:MIlb  -XH*"*J@G$Je_,K_+L **+"&'532654&##7326654&#"'6632+SS5?K)32#&&#"  .)*5N:"@pYe *2*5IL*\KCbA '^USr;'@$ J%K$L+3333#667###qr8{pPA E=>W3%M ;R%; '@$f%K$L +33373#7#rW.0XqY230R%Q!S0"F3"P\0r$B@? J$I_,K`+K'L+7&&5466773>54&'1[bEd.Q.YfK_1VFY*?6M0@3 vbT[ pdZY1Ko=GP.IV+IK[7F&(4@1'J`+K]%L((%(+7&&5##"&5467332667733267(4C+>IFYH &"NE1WP 81/1DA(G+ %0jX M+@(Jh%K$L&'+!7667##"&5467733266773F W8DEY'"#I@ Xr#B(4FC0{#(&_X87N0],$JKPX@%K`+L@%K$K`+LY@*(#"! 00 +"&5467332667733266773#7##"&'#>DEYG!#!H?4XH #!J@1XrH 1@)7<7D D@*F!$0fP-!%/jXc2"@77#7FN<;@8; J R%K`+L<<%%&&( +7&&'##"&'##"&54673326677332667733267'1A(7<6E)>DEYG!# I?4XH #!J@1XP% 91/2 @77#D@)F $/fQ+"$/jX &)#?@< Jg]%K_+L## +"&54677#7!6632'2654&#"FP^027SR-]B=8331* KO4KKC1S3H@(+"&)1>%p JKPX@g%K `+L@!g%K$K `+LY@%%  +"&54673663273%2654&#"P^?Y27QR-\qXr=8411+ KO4*ID2T2 >?),!%+/>!8@5 Jg%K`+L!! +"&546736632'2654&#"U^?Y3< [N1bAB;.98) LO3*P>1S3H>*$)&&4 !F@CJe_,K_+L +"&'53267#7354&#"'6632(D<#G[=: ;J0ebAi O \RJLE C seAy`9&KPX@!f_%K _+LK"PX@%f_%K$K _+L@)f%K_,K$K _+LYY@ &&  +"&5465##336632'26654&#"^a{3XrW.w S_`!A`9-I+51*?*4tZ sst[A{b:IF~U8D1Pa1:H&K(PX@ J@ JIYK(PX@ g]%K_+L@$g]%K$K_+LY@" && +"&'53267667&&54633#7#"37#"  !*"0-jjqW-A/,%3X%t5::F#. 2 B+Ia..(8$3,-#0&Hj/@"JKPX@+n f _ %K$K_ 'LK1PX@* f _ %K$K_ 'L@( f  g$K_ 'LYY@'% // +"'53276654&#"##73733#36632#<R"%"ND-XJIX  WA?HRI K c !%/jX\BZZB2#?&)CFD(KX&v0"!F@C  Je_,K_+L !!+"&54>32&&#"3#3267Yn!DjI#E7 8^:=';E dd=}j@ I OQJ  6JJ"VL\&'jo M.=@$%JKPX@!g_%K _+L@,g_%K_+K _+LY@0/64/=0=)'"  .. +"&54677&&#"#"&'532667>326632'2654&#"P^/*(5I:  .)'0H7>/7SR-]B=8332* KO4&_USr;L*\K?aC# KC1S3H@(+"&)1(rJKPX@h%K _ +L@"h%K$K _ +LY@!((  +"&5467##33736632'2654&#" P_2YsW/0X28RS-^B>7322+ KO4KC1S3H@(+"%)0 &v&\$7& tJKPX@!~%K`+K'L@%~%K$K`+K'LY@    +"&546733266773#7#773=IFYH &"NE1WrH 3DR(I- DA(G+ %0jXc2")F\%@"]#K$L+3!73!)U1ʒFKPX@#K]%K$L@]%K$LY@ +3373#r"Y0c*k&:C3+9&ZCk&:vr3+9&Zvk&:j3+9&ZjN\Y&<Cp3+&\C"5@U]M +77!QQ5@U]M +77!sQQ5"P7dD@,eU]M +D7!7!KYZ@@@@<@oL +'6673?H#C6 5~7;4<@oL +6673<8`H$;4 5~7t@t +667316`H#;4 5~7p@]oL +&&'73U65 ;9<$@!]oL    +'6673!'6673J#B7H#C6 5~7;4 5~7;4<$@!]oL    +6673#66736aJ$8`H$;4 5~7;4 5~7Mt*@'U]M    +6673#66737`I"6`H#;4 5~7;4 5~7i >@ JK)PX@ qKpL@ pLY@  +37737'zhFPXX I@ JK)PX@ qKpL@ pLY@  +377777737'7'}A2 iA4 WXXWa? @W_O   +7"&54632/@@/.AA:BC99CB:y&'P:&8J[lKPX@2    h g_wK  _pL@:    h goK_wKpK  _xLY@;]\LK:9('fd\l]lUSK[L[CA9J:J1/'8(8 &&  +"&54>3232>54&#""&54>32!"&54>32%2>54&#"!2>54&#"7< +B.9< -AN '&7< ,A.:< ,B7= ,B.9< ,A'&y'&JGNRG+GBOUJ.6V'=B:)%$8A<PJFORF+GAOUK.JFORF+GAOUK.B'=C9)%$8A<P'=C9)%$8A<PD#@oL +3D`D'*60+7'57p+R6+ 60+7'7'75+R=o6+ 'q@oKpL +#3O6EhGQ5)&f 3+G7@4ee]oK pL +37#73!!3#3#MTTnc6 BOOlBB&M@JJe  e_wK ]  p L&&%$! %# +#7667#737#7376632&&#"3#3#! 5<]^a`e]2X"K#7;  +(_J HACMCsR\E<5gCMC6CP 0@ - . JKPX@. f g]oKrK _  pLKPX@1~ f g]oK _  pL@5~ f g]oK pK _ xLYY@+)$#"! 00 %! +332##326654##"&5477#?33#3267ime?f4_323!7>54&&#" %=/ZSZv98_<Cl>$N?Qo97/O%|`Nm>I|NTm'OF(oX7Y3WT]z/F=C"D@A"JgeW_O  +"&&54>32!3267!5&&#"@Tt;.K\.JuDlN-IV"#:T#L41HN~HHhD C|U%<6%>%>&"U'E'{~*g^~3+^3+7"'u}'v*]}3+]3+D('z'(|*\|3+\3+H'8'*Y])}]3+}3+ @ JK1PX@5K^6L@b5LY@ +#73%!&5 \\I s?& $6l5Or`I(P/^*LKPX@nW`P@W`PY@ +"&547332673[UIM'..> T`^C6 #%6FTX 6JK)PX@ qL@ tY@  +5>73 S",X 48 6:^ 6JKPX@ qL@ tY@  +5>73",1 ^ 6: 48KO aJK PX@oU^N@U^NY@  +7#733#'37667 G;= ?l a4;a\/ _MG@DJegW_O  +"'532654&#"'73#6632;,726.! <   7@"MC3*"">i>7%I0qM$@!U]M +#7!q  q;0XU".9@6)JgW_O$##.$.  +"&547&&546326654&#"654&'8GnKD::5.$U2!$%+#%3%92X))#1A:((:0%7I "$")) *#)E +:JV^bfosw}aK PX@C / .JK PX@C / .J@C / .JYYK PX@4 1 p(&"%%&p 5 32e  U W76  g  g=<e:U;98!g#!?$>"&!"e/-+)%''%U/-+)%%'^D0C.B,A*@ '%'NK PX@4 1 p(&"%%&p 5 32e  U76  g  g=<e;:98!g#!?$>"&!"e/-+)%''%U/-+)%%'^D0C.B,A*@ '%'NKPX@4 1 p(&"%%&p 5 32e  U W76  g  g=<e:U;98!g#!?$>"&!"e/-+)%''%U/-+)%%'^D0C.B,A*@ '%'N@4 1  ~(&"%"&%~ 5 32e  U W76  g  g=<e:U;98!g#!?$>"&!"e/-+)%''%U/-+)%%'^D0C.B,A*@ '%'NYYY@~~xxttppcc__LK;;-,!  ~~x}x}|{zytwtwvupspsrqomigcfcfed_b_ba`^\YWRPKVLV;J;I><7631,:-:'% +!+   E+5#53%53!5353#75353!53"&54632%"'5326553%32#%2654&#"%32654##53!53%32654&##53!535353!533!53!53!53_^5`6B>>BB>>p =6T575." ""  +655B$"5`6_5`6^Q^6^6666^6^^66㄄QBCPPCBQ22- ) "',/3--33--3~򄄄5__5555555)d+A@>JHU_O! '% +!+%)+ 354676654&#"66322654&#"6g!++\P*X"(!>!& 8))((6{">1CJW"7'#%%#}&)K<\9EY@VJ~~ g_?K` 6L:::E:EA?4321,*&%  99 +"&54676654&#"7663232>7&&546323#6654&#"SJ    $(( $*-D2"aO[XF@1Hc0,,+[ P9#?#  C -"63 )3Q_Z!\UO`m  C0qo\8SS:,@3\fo@ JK&PX@_5K6LK1PX@5K_=K6L@_=K]5LYY@ %'+33>76632&&#":tYU?:7(   ?Q,6 2o`('GdM4>3I@FJ~]8K ` 6L.-&$33  +"&5467#77!##"&''2677332>54&'!DL82`s7X>1< F#,3 U= 5%,>$ XVFG$'K<9{jA1+,0IK8VI%O0Qe5<CO24(L&0v]3+3&Pva&$C0&"&DC 9dD@.gW_O      +D"&54632'2654&#"I1;;1/AA/622771271HC*c JK)PX@qK_wK_xL@_wK_xLY@$"**  +"&54>326673'2>54&#"Q1^TIl ,%`NG -YT<^B#ZN<`D$\ \I73F5 CV>#]}HO@; J_zK_xL" ''  +"&54>326673'26654&&#"]k"CeBj5/%_MI"Cd>/O/0(7Q,=o_>zd=FL2 BW'4=zd=IC~X9%K}K>DOc TJK)PX@qKoK`xL@oK`xLY@    +"&54673326736673/qo\Y] @IUZcY&5 _rQCDr i_3K49E[[`BD ObNr=7j$] JKPX@rK`xL@rKpK`xLY@ $$ +"&5467332667736673#7#=IFYH &"NE1W (3 _rRXH 3D DD(G+"%0jX=CD Pabc2"N4*@' JW_O%& +76654&#"56632 +/ 3?7/ NX 3(((/ 4)*&(C3+)&C3+0&HCL7&&XCmb%(@%$ J#K$L%%+&&73366766733673#.'"+] ( ]V+^/zP"_zEL)4l0T8w94;@,#(@%" J%K$L##+3.7336677&67336673#&&'% W'j XHr%W&qR Ch_251j1Q32&&#"!!3267YyFYY@>[xLcL%D,HkI,^Q)O'(P #$>pX2(J@i@N#]f N")KPX@& ' J@& ' JYKPX@" f_%K _ +L@* f%K_,K$K _ +LY@$" )) +"&547##33>32&&#"3#3267Yn{3XrW.yEiH$D7 >Z@8&<D bf?j@ I VJJ ;EJ0 0@-Jf#K$L +#3####3'&&'9PxX47ESH9  !7MMI D=$ 0@-Jf%K$L +#3#'##7#3&&'.9o\W&+1R6+r -5.P$-O) 8@5J f#K $L +3333######3'&&')Y@ϰQwX47ERH:^ijF  -7MMMG,8 A#8@5J f%K $L +33373#'##7##7#3'rX/n\W%*2R5*[|31p7!:@7 Jg]#K$L! !# +#7>7'7!#'&&####"7!(h5M>{;; Z &4 IYH%0&h87P/DD0P4=:V5.E:@7 J~]%K$L+#7>7'7!#'&&##"7#6_,B6l  -0U'/6Q606X #:&33(<(1*(2<)$'r@  JKPX@h ]#K $L@%pf ]#K $LY@'&$$! +33!'7!#'&&###"#7667#7!)Y@9y:; Y (5IYH$1&h]h!FDD0P4=;V4-#9!$A@> Ipf ]%K $L$#!! +333'7!#'&&##"#7667#7#rX/l  -0V'.7P4/4W\_3߬33(<(1*(3" <0 TU@4);5.&#"AUJGK(PX@)WgeW]M@.pWgeW^NY@SQPN%%%!-R +&&#"#"&54667>54&##7326654&#"'667&&'536632&&#"32632~1%(W2BH5`@&J<$RKf_1Z9<2-W)$*W2+=#9' $2FcU8I@710 @!= *%78&& LALg NFI^1 @U@5*<6/'$#BUJGK-PX@)~gfU]M@0~~gfU]MY@ SN%%%!.R+&&#"#"&&54>7>54&##7326654&#"'667&&'536632&&#"32632O))E01:!7E$'J0.7I1!@+(,!A'=!%=#8( $,1A=(3BnB7<9+J%+ -&/*("'J ('#C6 +$89$ <-6H  8->F$ % `sEH$9@6e_*K_+L $$ +"&54>32!6654&#"2667!Q1^Ty-YZN>bE?bCb] \I]}H  _i>nkCtI_i0#9@6e_,K_+L## +"&54>32!4654&#"267!]l"CeBcg"De78zd=pW>|g?@  9CX\R  >D\O@ JK(PX@_#K$L@#K_*K$LY@ %,+337667>32&&#"MX- %~ 2<0  -!;)R&#Y& CT(H>C/ ,@)J_%K$L$,+3336677>32&&#"n?Y*L'3( ,O2._ 1;@$&p\&a p3+) &b H&2\06&R\3H28@5("/JgW_O20&$ +"&'&&54>766327>54&'#"&'632?Xc,SuJ $WcKe %=@^3:3 $ ?^478-3=$oVxM !us{ hXR_fYLg&0M18@5+& JgW_O*( +"&'&&54>76632'6326654&'#"'IL8S8"HG/`I"@&8D!" & !<'&6 nU5k]C kNMf~" h-A  DlH4EG"a|@yQ.P/ A _ J~   ~gg _ *K  `+L$#][TRNLEC@?<:31-+#a$a#!""+663233#".#"7654&'&&5432"&54>32&&#"32677332>54&#"'632#"&' G4(DF* ':/. 9  /!nc4LbC)8 +[) 4(-J:(5..$BOY\7Qj@=IO>9?% $!MnD~c9,F5Xkn/O[' $7]pu3IJH+wkEg<)*1o#]|@yM.L/ ? [ J~   ~gg _ ,K  `+L%$YWQOJHCA>=:820-+$]%]#!""+663233#".#"7654&'&&54632"&54>32&#326773326654&#"'6632#"&'J G4)DF* ':0.0 9  !>ZV&D_9D&-%'=*-1#* "X# -6O*&#!:!GICgH+@A=9>8%  "%8oeC{a8C1O\-?I OL2C E iSCj?bv&M3+@,&N]Hx6@3  J_*K_+K'L&$'+7&&54>32&&#"32672n|=]|NdJ$C,KmH#]Q$EyAw]6(JCoD[g0"6@3  J_,K_+K'L%%&+7&&54>32&&#"32671Wj!EjH#E7 9V0>80Fc`?j@ I MN>; 84v 0+'7'77'77''?X"a#Y>Y$b#$P<:*7*75310.,))'%#"  ""(+D6632#&&#"6632#&&#"!6632#&&#"6632#&&#"!6632#&&#"6632#&&#"!6632#&&#"6632#&&#"2205'% 2205'% 2205'% |2205'% 2205'% K2205'% 2205'% 2205'% Y+45*,35*,35*,35*,35*,35*,35*,35*D#,5>GVdD@K ;:10,('$#"75JeU]M???G?GCB+D'6673'&&'7'7667&&'5&&'57&&'7%'6676673 !/ '!40"U'"$P&X&)^$)^$&X&50(y"$P0"U D !-&X&)^$"U'"$P0(!5 !/ D D !$P0"U' !40')^$&X&(D)#JKPX@+n~    h#K$L@*~    h#K$LY@))('&%  +"&5473326737#>7##3333UIM&//= T anvPT:hUThZ}C6 #%6FT@"KCwLEI7F00 KPXJ JYKPX@)n    h%K `$LKPX@(    h%K `$LKPX@/  ~    h%K`$L@3  ~    h%K$K`+LYYY@!00/.-,(&"!  +"&5473326737#7##"&5467332667733aUIM'..> T`sbE 2D+;KFYH F"NE1WbTq^C6 #%6FTb2!BC+G+E0jX2)9@6fg#K] $L! +3#73733#32#'32654&##)sKKYBsc)8\pCDF$NXXNaPryMJP60=({JK PX@%nfg _ +L@$fg _ +LY@" ((  +"&'467#73733#6632'2654&#"V\GIIX:@VR3b?=A34= NM2PCwwCKC4S0H:.(%&Z*8>@;  Jg]#K$L(!+332'##3267'76654&##*tb|$A(7B@;K>& @# #CDLgS=KQ bFJD1;5!.w@! JKPX@_%K_+K'L@!%K_,K_+K'LY@(&..*$+336632'#"&'#27'7>54#"H #X8AP"A.1;46B1 .<.*U!E:#2d,A\[HhW"]7%9/R"SUf5l1Tl<0<$& -@*e]#K$L +3#73!!3#)BGGEf3B;MBPM -@*e]%K$L +37#737!#3#2II2#2BKB*+#v@JK1PX@#g]#K$K_'L@ gc]#K$LY@##+"&'532>54&#"#!!6632(@:"<7510%&$$+7&&5447##7##"&'732>54&#"566323733>32&&#"3267%LLS2P3O )?W8! +C.,4$VVR1Q2O &=W9"  +B,*4& 7k\  -XH*H2Qa/:LHma (UH-G2Qa.:M' &['"&[*E.@+ Ja#K$L+7##333("JZZJQlT9b[F.@+ Jb%K$L+7##3733W'(8XqW6gY8 *7@4 J~]#K$L+3377373#'#7'*YJ^Blfp D6Ja}&rҸ+}X7@4 J~]%K$L+3377373#'#7'pX6:"@}g dX@$#88Px6^7)3@0 Jf#K$L +3#73733#3#)tIHYZZ'QlfJ$NXXN[b` JKPX@nf%K$L@f%K$LY@ +3#73733#3#KJWFni8\CYYC Z +@( J]#K$L +3#733#sJQmfJ{O[b&` +@( J]%K$L +3#7!73#na6gd8K *D0@-fa#K$L +7#!#3!33'VFFYY@:@XT9M.F;0@-fa%K$L +7#7##33733(I23XrW.0XbJ82)L -@*f]#K$L +33!3##!)Y@:@XFF.OM -@*f]%K$L +3337!##7#rW.0aY23K3*%z@JK1PX@$g]#K$K_'L@!gc]#K$LY@%% +"&'532>54&#"#!#!6632T(@;!32&&#"3227&&54>323267'>54#"1(D,v5bP =-HzK[O 7Q6@L$L; "%1>65!)bzC L Tyek#Y2=wa:UaAp'R!eu7bHyH(F0)"5B@2-3JKPX@(g_,K_+K_+L@%gc_,K_+LY@=;0.(& 55 +"&'#"&54>32&&#"3267&&5466323267'6654&#"8.VpBfG2 $2F*=: 'P=5CC?  'h/4%oo;vb;H0O_.@O@(:kCB@G(G~n72H 3H'x&&[0'"&F[ZDM *@'a]#K$L +7##7!#3'VvP8{OOFH"?i@ >)!JKPX@ a_%K$L@  a%K_,K$LY@??+&%%+ +7&&54677654#"#654&#"#33>323>323267'', D!H?3XG # J@1XrH 1@)7<7D)>D) 7(( -E0fPP-!%/jXc2"@77#FD' \Y<0"@J%K'L+7336673F2HX 1^2$a7PR9Y7(.4Y1HZR:#H@  ##\MF"4@1Jha%K$L""&'+7#7667##"&54677332667733i(K W8DEY'"#I@ XbJ8"B(4FC0{#(&_X82vA@>J~~h#K$L+!#7"&54733736673>;! CRR;Y:*/$D#:HZ# GC$# \6L!nJK PX@$~ph%K$L@%~~h%K$LY@!!+!7667##7"&5467737366773F :!>?IY ?>+I Xr&@1 yEC)*Eea9*;+@(Jg#K$L%#+336632#654&#"*Z=$`7PR:Z:)-4Y0IHC"$ K<,8@ )*JK PX@'ph_*K_ +L@(~h_*K_ +LY@75/-'%! ,, +"&&5467&&547333>32##326732>54&#"Sq:5BO  kUej+d~3bN=\10_gN!>1Y E{R02.# $cO[L5V>!ibR(9#--|$;"*5K@H'(J~g_,K_+L42-+%# ** +"&5467&&546733>32##3267326654&#"V\e3@ M /FfAGS=r:>%G&(N8gA( 0Y m]  *3+ !%BnB=@1V6 =GK91*Y32##326732>54&#"P&bf5BO  kUej-g!bN=\1*S;$gN!>1Ym02.# $cO[L6W= ibRL(9#--|$F;".9@ )*JK PX@, p h _,K_+L@-  ~ h _,K_+LY@861/..%%# +7&&5467&&546733>32##3267326654&#"%@D2A M FfAGS=r:>%G&#A%#Q8gA( 0YfL  -3+ !BnB=@1V6 =GK1*Y},j&$3+i&$* g@JK1PX@]#K$K_'L@c]#K$LY@  +"&'532>54&#"#33'@; J]%K$K_'L   +"&'532654&#"#373 5.UaG7#.XqW6g+K/ @c R tGL.XEBx\6E!KPX@ JI@ JIYKPX@]#K_$L@(~]#K$K_+LY@!!%(+7###"&'532667>7!3|vV "!4L: -)%&%cY{z1uyo+?\1NA<.x<F#h@ JK"PX@_%K_$L@!_%K$K_+LY@##'$&#+7#&&#"#"&'532667>323+bVe *2*5I;  .)*5N:"@`Tr'^USr;L*\KCbA >*j@ JK1PX@f#K$K_'L@fc#K$LY@ +"&'53267!#3!3)@B$hh8FYY@:@X" U oz .i ;A@>Jf%K$K_'L +"&'532677##3373"37?E,3XrW.0Xoo T\hy*D6@3~f#K$L +7#!#3!33vWFFYY@:@X\|M.F;6@3~f%K$L +7#7##33733dbU23XrW.0XbTq2vE7@4Jh#K]$L%#+37#"&547332673#8Q-$a7PR;Y:(.4X1IZU) GC#$\6aF&!4@1Jha%K$L!!%'+37667##"&5467733266773#7I W8?JY !%$MA WqJ(M"5#&2ED(+"%'aX5(EL6@3 J~#K$L+7#667####3333>vVZGL [T~E=Z{AlrCM!SGG6@3 J~%K$L+7#667####3333bHA E=>Mqr8{aPp3%M ;R%W3},T&$$*3+01&D$&$j-3+0&&Dj `0")N&($$3+0&H$(s*C@@Jg_*K_+L! %# *!* +"&&5466336654&&#"56632'267#"I\+U3%K:&D(&I3]e%Fc90Y# B;5U3 =GKm]@}g>IYQ1)!(s&jG3+&jj&j3+i&j &j3+&j">@;Je]#K_+L +"&'5326654&##77!7!*^#&\.FT%K@NUo? T.H(:5FPGVXAk?@@=J~]%K_'L +"&'5326654&##77!7!_7KS6?T)WL% k 1Q0B|Q2V5HBJg#K `+L$"((  +"&'#"&546633332773%2677#"8B T8MbM]B@Zr)%T2[1_>?"7^t3 ,%((VVPo:.%'jWcOC(O[+30'6N@K $J~_,K `+L)(1/(6)6"  '' +"&54>32366773326773#"&'#'2>54&#"CO$C`=7C %Wv((44 V aX@O $`$!D:#14(B/ ]ZIi=7% >( (.@@g]=4/BI0Tl=0<3Vl8lw2KPX@ J@ JYKPX@e_*K_+L@&~e_*K_+LY@/.+) 22+"&54654&##7326654&#"'6632326773P\7%/+9@gSI"1L@I J~e_,K_+L.-*( 11+"&54654&##7326654&#"'6632326773PP./N6$>&'-"B$+T+LZ@?Y&)35 W ` EA  ,J'#&C@>5HX "&@?g]sD*@@= Jea_*K$L**%%!&+7#76654&##7326654&#"'66323}(V%@Fvf1W58.3W*%1nCZ_fR?@R9 /5I!C3.0@ $YFPaG6#ZKG")@@=Jea_,K$L))%%!&+7#76654&##7326654&#"'66323"'J..O5#?'(,#A$+T+LZ+0K7t &J'#&C@>n5)$ %Q0B@?J~]#K_+L('!00+"&'532667>7!326773#"&5467# -)%&%NhQ34.X2dTG^ U "!4L NA<.x<#$ L:?gUHL'+1uyo+?\12~@$JK"PX@ ~_%K_+L@+~_%K_+K_+LY@.-*("  22+"&5467&&#"#"&'532667>32326773JU9 *2*5I;  .)*5N:"@FP60 X# -S IH!'^USr;L*\KCbA O?@8S/*aKPX@f#K_+L@ f#K$K_+LY@  +"&54677!#3!3326773G_FYY@:@ZmR35 .Y3d HL"w. L:?gU'oKPX@#~f%K_+L@'~f%K$K_+LY@  +"&54677##33733267733KU3XrW.0XIQ50Y# .S IH ' P@?8S/H#>@;  Je_*K_+L ##+"&54>32&&#"32667#7!O|8fV@b,"&P7SK#L@DV1  ,Ho ^}GNal:[45dDO>CtV00%">@;  Je_,K_+L +"&54>32&&#"3267#73 it)RwN6T#!B.Mf3CFMO   vgDy]5FGzJ@SUBI0sZ`5@2~]#K_+L +"&5467#7!#326773aG`Z]R34.W1e HL!OON L:?gU*5@2~]%K_+L +"&547#7!#326773 KU 79Q6/Y# .S IH$KK O?@8S/9B,J@G)*Je_*K_+L'% ,,+"&&54675&&546632&&#"33#"3267La.lb4<>i@A]&."F.:U@LXV=`8FF6Z($b 0S2Uk L6BZ.$!?C@2@IA85AO!<*KPX@JI@JIYKPX@c]#K_$L@*~c]#K$K_+LY@'&%$ ** +"'53277###"&'532667>7!3$* Y "!4L: -)%&%cM ; I 9@z1uyo+?\1NA<.x323R ) Xe *2*5I;  .)*5N:"@aL;I9@'^USr;L*\KCbA =C8Q&$ 60Q&"&D 9&$Ht3+0&4&DHQ&$Sm3+0,&DSJ&$Tm3+0&,&DTJ &$Um3+0^[&DUJ\%&$Vm3+09s&DVJQ&$' 6Jp3+0Q&&D' 9JM'&$Wq3+0&L&DWN'&$Xq3+0&L&DXN' &$Yq3+0&n&DYNX%&$Zq3+05s&DZNQ'&$'M} 63+0Q&&D&MZ 9)Q*&( B0Q"&H 7)*&(Hh3+04&HH5)C&(Qg3+0 &HQ/)&(Sg3+0j,&HS/)*&(Tg3+0,&HT/){ &(Ug3+0C[&HU/)V%&(Vg3+0s&HV/)Q*&(' BJj3+0Q&H' 7J2&,H3+N4&'HQ}&, Q&L HQ&2 0Q&R KH&2H3+04&RHDH&2S3+0r,&RS7H&2T3+0,&RT7H &2U3+0K[&RU7H%&2V3+0&s&RV7HQ&2' J3+0Q&R' KJ:HC&Dv3+0&EvHC&DC3+0&ECUHC&DH3+04&EHDHC&DQ3+0&EQ8HQC&D 0Qj&E 9OQ&8 7Q&&X 6O&8H3+7&4&XHSOc&Fv3+7&GvOc&FC3+7&GChOc&FH3+74&GHVOc&FQ3+7&GQHOQc&F 7Qj&G B\QY&< &\  3+\Y&<HG3+4&\H \Y&<QS3+&\Qb&Baz^;, ?@<J~qL    +566737>73#&&'t3W +/0-[ -".D 6 %% _ ,.K +-1^, ;@8J~qL    +&&''37>73#&&'.G !80-[ -".D8 9 _ ,.K +-z^[&l@  #JK PX@pgqL@~gqLY@&& 3& +76654&#"566327>73#&&'h!"  %0)#0-[ -".D/ (#e ,.K +-{^s)A@>&J g hqL))#"$!$! +63232673#"&'&&#"7>73#&&'U$ 2S$ E0.[ -"/Dl l   ,.K ,-^L kJK&PX@~cqL@"W_OY@     +56673"&'332673*V .4:I6*8N 4 %% D=  8I^L jJK&PX@~dqL@"W`PY@     +&&'73"&'3326734G " 0;H6*8N8 ; D=  8I^n# JK PX@pgcqLK&PX@ ~gcqL@*~|gW_OYY@! ##%& +76654&#"56632"&'332673!!   &/)#:I6*8N0 ($vC>  8I^s%wK PX@"g h c qL@- ~g hW_ OY@#" %%$!$! +63232673#"&'&&#""&'332673V"  3R&  [;I6+8Nl l B=7H'`N@ JKPX@`'L@W`PY@  +"&'732654'3 "< >7$0,94?<K0@-JW_O +"&'5326773"  M!@I B0NM&7zl&Wzs. JKPX@'fqK _zK _ xLK)PX@+fqK _zKpK _ xL@+f _zKpK _ xLYY@! (& .!.  +"&'###73733#36632'2>54#" 6C!BFFX$U8BQ$D`D(B/U!E:#2 7%R]BYYB#L7,A\ZIi=I3Vl8l1Ul;0<P'0vJK PX@&pe]oK]pL@'~e]oK]pLY@0.*('% 5! +3#"#&&546332#326654&##32654&##u$(KNScqXI1BG|O4u,J,Jp}#% @ONVI[ H54#" 6C!B $U8BQ$D`D(B/U!E:#2 7%RJj"B*,A\ZIi=I3Vl8l1Ul;0<E2@/foK_xL  +"&5467332'2654&##lbkY@gOd.?uPHaOHf WI0R3Il32'2>54#"SgiX' 3@'IN#EeB,D.U'G62 \_/81 2#_\Gh=I6Yh3o8Yg.8;)&q ʰ3+HZ+K@H ()Jg_wK_xL&$ ++ +"&54>3276632&&#"&&#"3267Fw=]|N9-A+  Q/KmH#]R)O&'O @v]6 !A1I zCoC[i N0I*t@'(JKPX@ _qK_zK_xL@g_zK_xLY@%# ** +"&54>3276632&&#"&&#"3267Yn'Ih@ B+  )6!9V0>8#?E ddHb9nB0I!ML=CJ!|P [K PX@p]oK]pL@~]oK]pLY@ 5! +3#"#&&546332#'326654&##u$(KNSāaGLhJiWU}#% @O|oM^dna0> 9@6g]oK]pL      +!"&546337!7!'3#"rd@/L7>\pGbOsxO6MJQ610U( JKPX@"]qK_zK_xLK)PX@&]qK_zKpK_xL@$e_zKpK_xLYY@#!((  +"&54>3236677!7!#7#'2>54&#"AP$Ea=6A H $V!D:#/5(A0 \[Ii<7%">$eJc-@I1Tl<0<3Vl8l ~' 3+ /@,e]oK]pL  +37!7#7!7!7!60jONO6(s!F-J@G*+Je_wK_xL(&" -- +"&&546677&&546632&&#"33#"3267 Qg07_=0;?lC-B;$)%K6>TDNY]i|HF2i/.e 1R2ET,  G8C[.=DD0;KHT4<R*>@;Je]oK_tL  +"&'53267!!!!%  & j5RF L#/OOTIHZ/R@O Jge_wK_xL,+*)&$ // +"&54>3276632&&#"&&#"32677#73W7gV(A ?,  /[3RL'R@&?.L-d bG 'A0I }bo7Y4 NG"1@. JoK_tL"" +"&546736673'26654&'.5<8_Y4  *fD< ">/1vG_)Q$#R'scGIbN"2*3M#W1ĵJKPX@qK_zK_xLKPX@!qK_zKpK_xLK)PX@%qKrK_zKpK_xL@%rK_zKpK_xLYYY@.-*( 11 +"&546776654&#"#33>3232673'WZ "!J?1XX+1A);F_:@EYEm ND   !%/jXA 2"ED(TIOAxc3+@(JoK`xL +"&5467332674GqXr  3 4A%  C }3@0JfoKpL +#77#737'733# U7SR3L V3TT6M 1N22N1)T@  JK(PX@_oKpL@oK_wKpLY@ %% +33776632&&#"#)YJ>'6  "bS<B(GpZ= Y@JKPX@_qKrKpL@grKpLY@ %# +36632&&#"33#'>?!%haqH(qEG IPW9 HK)PX@fqKpL@fpLY@  +3#7333#L@@HXIBBKbBTB+KPX@(!  )J@(!  )JYKPX@_qK_xLKPX@_qKpK_xL@gpK_xLYY@%$ ++ +"&''&&5#''7&&#"'663273267*.]0hm &:>ag9 ! -: P&"? ? <"F,/= BD)]&!JKPX@oK`xL@oKpK`xLY@%#  )) +"&547332673326673#7##"'#F\kYk,+RX`Yk++9I-\XA?ro'd ON+0d^)06`@6R\d31:@7 JoKpK_tL  +"&'53267336673##&!  % _ TU_ fA L#/$o26PEP$ FL "H_H$4g JKPX@_wK_xL@_wKpK_xLY@&%.,%4&4 $$ +"&54>326632#654#"'2>54&#"O2^R@c &d6PSjYkX-J-XQ9[@#YI9^D%[ ]I.+(1SHX'=M]}HOJI_zK_xKtL%$-+$2%2###&)$ +654#"#"&54>32663226654&&#" }A4"Bc@Ye"CeBc0P'?A}-L/)#7Q,6IG+=zd=o_>zd=G%%H@1C~X9%K}K>DP bK PX@!pg]oKpL@"~g]oKpLY@ $5! +3#"#&&546332##32654&##t$(KNStb@;K>`qCDL}#% @OgSybRY;5&5~@!JKPX@&_qK_zK_xKtL@$g_zK_xKtLY@('/-'5(5&&&)%# +6632&&#"36632#"&'#2>54#"7>54&#"'66323267_r)DU,=L%:2&G#'^1Yf;e@ET&B:4U%"[ ZS9L2#(5**1L`IBV9'1).6N "*7@4'(J_zK_xL%#** +"&54>7>54&#"'66323267S^"7A9>+(B"&S)LV2X9#=%/1+J! J ME):' !#EG=6A' &"(M3n !-m@ JKPX@g_qK_tL@gg_tLY@#")'"-#- !! +"&5467#"&54632326737654#"4G:7AF78  3 %4A'S=+4C>0  _  C [  ),l'@$JK PX@'n]rK_xK_tL@&]rK_xK_tLY@"  '' +"&'532677&&547#?33#3267o  4E =SZ>4>(+AI!b4? '#(&ozC ! B0PtNK PX@p]oKpL@~]oKpLY@ %! +3#"#&&5463!#\%'KNSć{!% @OO,'w@$%JKPX@!_qK]rK_xL@g]rK_xLY@"  '' +"&547#?6632&&#"3#32676J =S\GI& $<>" 2 4A '#('?MM IDUC ! C ZM5@2J]oK_tL  +"&547#7!#3274@ė0 (96OO6/ LJ&4@1J]oK_xL && +"&&54667#7!326654&'7!#XZx<8`; Dk>'P?Om87/&O(]@ JKPX@_oK`xL@oK_wK`xLY@(( +"&5467332676654#"56632,pm\Y]EDYVA1!//DCEt g_1L28@\Y/ 6N 8=  Nr=PmeKPX@ J@ JYKPX@_wKpL@oK_wKpLY@ $# +3&#"566323:L $/ ;e7 Z#G#/`?"(d@ JKPX@_rK_tL@rK_zK_tLY@#! (( +"&'53267733>776632&&#" (:#QX# n/% )XG20> !LE@D8)AKK=3@0e]oK]pL +#7#737!7!3#!  uOF GPGGP3@0e]rK]pL +#77#737#7!3#3 _E}_ 7'7!!#"3267un/Pe6ɭ ">mCMI.e/.g hR@;Jg]rK_tL  +"&&54667'7!!#"3267F`1OM t 7>e;M<6N"!X5\:Ws;@J=(TAAGM(@@=%&J~]rK_tL#! (( +"&546676654&&##77#7!3267mQW#UJR^)E+2 k Ja=-+-/MP>5(6# 5@%(=J@QI]]  L  dJKPX@ e_qK]pL@ge]pLY@ !%% +#7#736654&#"'66323#!,'/',J#*(b;8O)'*aGKF3V1&/$Je]oK_xL  +"&'532654&###7!#322`%&a.^gO@e;N,lm R[TB> PPjWwA@>Jg]rK_xL  +"'5326654&##7#7!#32m4Q2%G/L?D)?YAO#x #O8/+)JJu,G&Yq'f@ JK PX@n]rK_xL@]rK_xLY@'' +"&'532654&'&&5477#?33#,SL,J=,%SZ>415t O7!')%[(&ozC] >1OX!JJKPX@_rKtL@rK_zKtLY@ $ +336632>54&#"H U=KI?pW1@AoT.'/+J6 e,B_MIhC 37Sc5.=Ak?>.0K)PX@ qKpL@ pLY@  +33>N>&@`K)PX@ f eqK  p L@ f e  p LY@ +3#737#73733#3#96N69 H_HH_H)&''=K3+)v&'']K0&G']CKW)B&/-)&/M&OM(B&1-(&1MP&QMC;&$Kt3+0&&DKQ&,K3+}&'KH&2K3+0&RK>O&8K3+7&&XKWO&8z3+7&D&X#O&8z3+7&g&X#O<&8z3+77&X#O&8y3+7&g&X";&$@3+0&D&D9&$0&D&D`W&L_3+0&LH)P@M  Je e_wK_ xL&%$#"!  )) +"&54>32&&#"32677#737#733#W7gVAb,"&U3RL'R@&?!??-d bGNbo7Y4 EGGNG'")9@  JKPX@,e _zK  _pK_ tL@0erK _zK  _pK_ tLY@!+*31*9+9'&%$#" )) +"&'53267#737667##"&54>323733#2>54&#"1SY+1< #V8AQ$Ca=6A!C~AL k$"C8"-5(B/,QG/@,AXZIg<8%SGA:9/Rh:0<2Tj861H&*K3+'&JKM)&.K3+ &NK3+H'&2P0'&RPH'W&2'LP3+0'&R&LVP"&KQ3+&K)&'=)R&']0&G]CH&*v73+'&Jv)giKPX@ foKrK_xL@$foKrKpK_xLY@  +"&5477!#3!332673UMOFYY@@Xn#$.0EYE1N MC.)%DNAOa+wJJKPX@_oKtL@oK_wKtLY@ % +33>32>54&#" H2J84O.1Dud=7Pkj 51X:̗5=+h?Aw(&1C3+&QCo&$ 3+0&&D c&$ ?3+0&&D )*&( 3+0&H H)*&( 93+0&H }&, 3++&' &, 3+\&' H&2 3+0&R PH&2 3+0&R  )9&5 3+&U .)9&5 E3+&U O&8 3+7&&X iO&8 y3+7&&X "L=+#@ J# G_wL +7>54&''>54&#"'66324[~H/'&P)>nW1:6;f4BB4V4TH%9=kV7HbB*7  H"+>-(,@( @1IfM7FoUA2")#@ J" G_zL +7>54&'5>54&#"'6632DHl?! G&IqB/+,Q)3c1.O0F8"*QO*>S7'-  B,B1&&@?08Y<6NpN4*&+K3+ &KK3+)TJKPX@_oKpKtL@oK_wKpKtLY@ $& +6654&#"#3366327?AeEOYJ"sI[c #7=K|Gu:F]\$+C02AL@#K0JGK)PX@0gqK_zK _xK `xL@0g_zK _xK `xLY@CB43IGBLCL<:3A4A$*&* +'667&5##"&54>32366773>32#"&'%2>54&#"2654&#"@ 2FP%AP$Ea=6A %Wu)?/87XF-!D:#/5(A01'&4i B P)B&\[Ii<7%">$-7"9*>2=1Tl<0<3Vl8l2(,$1<@9JgoK`xL&%,*%1&1$$ +"&&54667&&54773326773'2654&#"Ag<2V6")Z=7KYYK@-?PVasNB;^7F 1_C@`?A2XX56XDX^FaZ?Wv:;N(@ j\`;,~ -)EP~RWP<9iT1I=e=:D:b=32632#"&'72654&#"P;8 "%"ND1XrH 3C+>I77RA*: " 0O  ($/jXc2"D@ -cB,=E#,?*l+y@)JK PX@%ng]rK_xL@$g]rK_xLY@! '% +!+$" +'667667#?33#632#"&'72654&#" ;98SZ>4586RA*: " 0O  (&ozCB,=E#,?*0S(7Fy% JK)PX@!qK_zK  ` xL@!_zK  ` xLY@!98*)@>8F9F20)7*7#! (( +"&54>3236677336632#"&''2>54&#"!2>54#"HS$Ea=6A %X& $U8BQ$Fe@DS 4P+0H131(A0(B/U!E:#6 \[Ii<7%">$"B*,A\ZIi=A<:%I1Sj:0A3Vl8l3Vl8l/Sk;4=1 T" 3+'t@ JK)PX@" fqKoK pL@" foK] pLY@ +#373#'###37&&5#'9^5BkEXC.t-y*p A7e).,&W,{{Hx!+u@ $ JK)PX@ qK_wK_xL@ _wK_xLY@(%!!%)( +7&54>3273&&'3267#"'"#"WBQ=]|NB# $#):)O&'O8F60 ! KmH#K}I@v]6&1 J N\TL1Coo!)@$ JKPX@ oK_zK_xLKPX@ _zK_xLKPX@ oK_zK_xL@ _zK_xLYYY@'%!!%)( +7&&54>3273&&'3267#"'#"a'IgAMBS  &#?E)5(P@ 9V0K3Hb9I JP%YM -@*foK]pL  +3#7333#!)FPPBYC5LG7GPW"jJKPX@ n ]oKpL@ ]oKpLY@ +#7!733##7737g=H=3YXZ/c1!OXXOdHH"8M@J  56J_zK_xK_tL31,+! 88 +"&'&&'&&'532654&'&&54632&&#"#3267G@  P*;>&49:cS1S@,,2$44Cof !   &KR$#Q.&' D3DTF ) &A8OV (-'H =@:J]rKpK_tL  +"&'&&##7#7!3267K=%-% ME.* # 'ON+(<BGoDA,( I C)@&  J_wKpL%( +3>54&#"'6632CD(SG,:2$P#!)b7\eEsF9B#1D/1=HhRGfG$")@&  J_zKpL%( +37>54&#"'6632?(OA'<.(@##)U8Wem$2D-1@EfRh#]M+I@F Je e]oK] pL+*)('%!! +37#7332#326654&##32654&##3#)$KKccqXI1BG|O4u,J,JpNNVI[ H foK _ xL$$  +"&54677#733!33#'2677!,pmII=Y=G=Y32733267#"&'3277"6654'7#0+%Fc> sH}8bmR1&D(&I32u#Y8V"+ -/6U@}g>!GAcK _6 ,!S  dB!:@7JfcoL  +"'73267#7333#P2$,D ALLDYDKKBm M7A1NBNeX  @  JK-PX@&f _wKrK_ tL@$ gfrK_ tLY@    +"&54632"'5327#73733#-$% =CEE.W.EEEIq&-# Jb=GGKXH(;@ %&JKPX@"_wK_xK_tL@&oK_wK_xK_tLY@*)53);*;#! (( +"&5477667##"&54>323733267266776654&#"G1E aFux0]TD\$I  &>[< YJ=`C"T4;g%)=YJ@/d L49a3237332672>54&#"0?#V8AQ$Eb=5A!B )!D9#.4(B01=?@,A\[Ii=8%S C /2Ul:,@3Vl8l97@4 Je]oKpL! +3#7332##32654&##)>PPIQavbfu>NNd[ECL'LWMr'sWE=0 "{KPX@ JH@ JYKPX@f_rKpL@ frK_zKpLY@$% +37#73733>32&#"3#5FF.H .:& 'A1pv5Gc2 O(C(G5Y4@1JfoK pL +3'#73'33733#7#:?\7!YTeW;_7c NNd(H@E J frK_ tL$#  +"&'532677#73'33733#3>77# (:#,P6X^^`AY)X xG20>(GGKK8@D.!LE7 !+u@JKPX@f_rK_xL@#frK_zK_xLY@)'"   +"5473363232677>54&#"J=EaCX2Re3Q2&&H#%YlD0W70&9Y ^LVJF8H' *#B32$'KN0&"D"DB 3+$3@ JKPX@"_qK_zK_xLKPX@&_qK_zKpK_xL@$g_zKpK_xLYY@&%-+%3&3 $$ +"&'##6632&&#"136632'2>54#" 6C!B=?! $U8BQ$D`D(B/U!E:#2 7%RpEH IV2$,A\ZIi=I3Vl8l1Ul;0<"7@4J_zK_xL  +"&'7326654&#"56632~#E7 9V0>8#?E)Yn'Ih  I ML=CJddHb9"&2L@I0%JIGg_zK_xL('.,'2(2$'%+ +'667&&54>32&&#"6632#"&'72654&#",6''Ih@#E7 +F3%Q/B>fS,K23  F .1 <0Hb9 I ,J]1#&I/HH(=)#"0U+:@ ()JK)PX@&qK_zK_xK_tL@&_zK_xK_tLY@-,53,:-:&$ ++ +"&5477667##"&54>3236677332672>54&#"0?  $V8AP$Ea=6A %W )!D:#/5(A01=?A-@\[Ii<7%">$ C /1Tl<0<3Vl8l0#2@ JKPX@"_qK_zK_xLKPX@&_qK_zKpK_xL@$g_zKpK_xLYY@%$-+$2%2 ## +"&54>32366776632&&#"#7#'2>54&#"AP$Ea=6A ++-SM J-M1*G,EX:a;B{`99AF-#1)"!0 "*?@< Jg_zK_xL&$ ** +"&546632'26654&##732654&#"mhG`P]><)2>i='A(<;)@R..I^- t_bZH=4D  7-;O'I-#+"H'2 $J|I=@:JfrK_tL  +"'5327#73733#@% =CEE.W.EEEI Jb=GGKX3B@)*JKPX@+_qK_zK _xK_tL@)g_zK _xK_tLY@54=;4B5B.,'%33 +"&'532677>1##"&54>32366776632&&#"2>54&#"1SY+>P  $V8AP$Ea=6A @;  Je_zK_xL  +"&&546632&&#"3277#738Z4Ha0LB!I^/s6-j;)N.]Fa[GI{IG'1@.! JrK_tL'' +"&54673366773'26654&'/6A(U[(  .] :(  >+7h5U! U 7,Q"'H/I$1.2-"/;B@?"6)#J_zK_xL100;1;'%  // +"&5467'&&#"5632366776632&&#"'2654&'-3<%U  # 0 \+ 6# & 6*6T& A h)(jA(B#>'I)$77&'@$rK`xKtL%) +7>1##"&546733266773*0 3D+=IFYH &"NE1W5)2"DA(G+ %0jX *b@JKPX@_qK_zKpL@g_zKpLY@**%*%# +36632&&#"3>32#654&#"=?! 2C+>IFXG !%"OC1pEH IV42!ED(P-!%/jX 5@'JKPX@%_qK_zKpK_tL@#g_zKpK_tLY@-+!55 +"&'5327654&#"#6632&&#"3>32 <V !%"OC1X=?!3C+>IVIJc-!%/jXpEH IV62"ED(lJX  iK-PX@!f_wKrK pL@gfrK pLY@      +"&546327#73733#.$5GG.X/JJ4q&-#GG3@ "@ JrKpL  +#77'73 MUG LUF 444s4~aJK)PX@ghqKpL@ghpLY@"#"" +3&#"#6632332673#"'HO  4:+CXM  5:+Ft>B=>B Xi JK)PX@g hqKpL@g hpLY@$! +3#"&5463233#376654&#"Q?98=9 :XTaa?():)/? yHq I@ JK)PX@qK_tL@_tLY@  +"&5467332674GX  34A)& " C \!@JK)PX@(~qK]rKpK_tL@(~]rKpK_tLY@ !! +"&'5326654&##77!#3!7KS6?T)WL% bXX0w 1Q0B|Q2V5HB<2@/U=MwE7N0],$JKPX@rK`xL@rKpK`xLY@*(#"! 00 +"&5467332667733266773#7##"&'#>DEYG!#!H?4XH #!J@1XrH 1@)7<7D D@*F!$0fP-!%/jXc2"@77#7N43@0 JrK`xKtL44%&&) +7>1##"&'##"&5467332667733266773R0 1@)7<7D)>DEYG!#!H?4XH #!I@1X5)2"@77#D@*F!$0fP-!%2lX3";z@-%JKPX@_rKpK_ tL@#rK_zKpK_ tLY@31+)$#"!;; +"&'53276654&#"#654&#"#33>323>32. <W!#!H?3XG # J@1XrH 1@)7<7D)>DVIJc!$0fPP-!%/jXc2"@77#D@*lJX "(m@ JKPX@_rKpK_tL@ rK_zKpK_tLY@"  (( +"&'5326733>32#6654&#",!H 3C+>IFXG"%"NDF>I c2"D@/P!$/jXEG "-m@*+JKPX@_rKpK_tL@ rK_zKpK_tLY@(& -- +"&5476654&#"#33>3232670@V"%"ND1XrH 3C+>IU )1= !$/jXc2"D@/s  C F$@! JrKpL +33>73#qfBUqe ?P00 6 240`0))KPX@ JK"PX@ J@  JYYKPX@#e _zK _ xLK"PX@+e _zK]pK _ xL@3e _zK]rK]pK _ xLYY@$"))  +"&54>327!#3#3!7'26654&&#"]k"CeB5II$ B2N-0(7Q,=o_>zd=($EIII0IF}S :%K}K>D-"/C@@J~_zK`xL+)#!//  +"&54>32#"'#'2677332>54&#"KL4d[Vw>6W=nH)-: U& '5 _\RL bSOf:CuJ2iY6Z,.IF<'%(BQ)ScI`i0rqfKPX@ J@ JYKPX@rK_xL@rKpK_xLY@  +"&'73266773#7#2N4 4XrH .: OBf5c2 KPX@ J@ JYKPX@qK_xLK)PX@qKpK_xL@pK_xLYY@  +"&'7326673#7#2N4 dXH .: OBf5c2 q(B@? %&JrK_xK_tL#!(( +"&54677667##"&'7326677332670?.:&2N4 4X )1= ?A2 OBf5 C "cKPX@ J H@  JYKPX@_rKtL@rK_zKtLY@ $% +33>32&#"H .:& 2N4 gc2 OBf5"$|KPX@!"JH@!"JYKPX@_rK_tL@rK_zK_tLY@ $$ +"&54733>32&#"3267v0@H .:& 2N4 C )1=_c2 OBf5  C j")@& J_zKpL%$ +3>32&&#"P1G.+ @P{AI J \( ")@&  J_zKtL$% +6654#"5632(3' */=?h 5 K?7 3@0 Je]rKpL! +332#'#32654&##rNX)D*b]Xn-&49:cS1S@,,2#5"6q_* (/@.&' D3DTF ) '(5%QTG  C ~X@JKPX@_qK_tL@g_tLY@  +"&'53276632&&#"? ?HL" "* MJrPaI:8S^~"w@JKPX@ e_qK_tL@ge_tLY@ "" +"&'5327#736632&&#"3#? ?@DD9HL" "* 7GGAMJr-G PaI:8GS^ "%7@4"#J_zK_tL  %% +"&5476654&#"566323267{0@_ )0@_ )1=  C 1=D C =~%u@ JKPX@!g_qK _tL@gg _tLY@" %%  +"&546336632&&#"3#'267#"B>C[R1}HL" "* zLK1@'" +0<1ABLPaI:8HBIH+5"("WG 3+lf@ JK PX@n]rK_tL@]rK_tLY@  +"&547#?33#32676J oSZ>4p" 24A ' (&ozC ! C @&t JKPX@  frK _ xL@#  frKpK _ xLY@$#   +"&54677#73733733##7#'32667#=I CD-Y--W-GG6H 3DX &F@ DA(,GGc2" %&SE6+(E 4@1J]rK_xL    +"&5467#73326654&'73#ei4<`IM==/Q0+&q@=yy_L0IEe>N4oX4REI@]TW@%"'qKPX@ JH@ JIYKPX@_rK`xL@rK_zK`xLY@'' +"&54673326776654#"56632a]>X>2;BN1( 7G `Q$)"432##732654&#"; MEL%;>*29aUUE:+,1X <BGq4H%;(A?)k! .%0[@X )#J G~g]rK_tL'&,*&0'0 %% +"&54632654&##77!7!&&''267&#"]KbcM4Y$ WL% k 1Q0& ?  "b;&IBN2(1@ACD$#%HBO=/("HB% @E@  JKPX@_qKpL@gpLY@ %' +3>54&#"'6632@M?c97) H!!&\1T_+eXCkBX7-6B\H3l^UG@  JKPX@_qKpL@gpLY@ %' +3&&546632&&#"CG7*pBHf5 ?QI:^nK@  JK)PX@qK_xL@_xLY@  +"&'732654&'37M,9$:S?DLYDF832&&#"3267_^ 0HfC%E83O:$;5#:@wq/u}t]7 I 9b{AVJ KH&2*+ +3+) 9@6Je]rK]pL  ! +332#32654&##32654&##)q\Wy0&zb.a:6.5NTd??)3`A:j @YR:*/#u<1#"(?@<Jg_zK_xL$"!((  +"&54675&&54632'26654#"33#"XmKD*1o]rr@YGT%6=<; JV> LG;D  21JTi\VKGrA,&+!H/2'*0t.@JKPX@(e_qK_zK_xL@&ge_zK_xLY@+*)(%# .. +"&54663276632&&#"&&#"32677#73ZpD_*@,  '?F[,:8-o:)N kh_]sB0I!}IJzG@HG;O  #{K-PX@'h _wKrK _ tL@% ghrK _ tLY@!  ##    +"&54632"&5463333#'267#"-$<@[S qWrLKF< 5q&-#=0@CH[MH2."()@& JrKpKtL +667##73773EhaqH(Y>PW29g@rK^pL +333rXc1I0'6}@ JKPX@&_qK_zK_xKtL@$g_zK_xKtLY@)(1/(6)6''%)&( +7>1##"&54>32366776632&&#"2>54&#"*0 #V8AQ$Eb=5A 54&#"'66323#@#SR?c97) H!!&\1T_+eXdd"I~BX7-6B\H3l^PIO_@ JKPX@e_qKpL@gepLY@%' +37#737&&546632&&#"3##dcG732366773!3!7#'2>54&#"#AP$Ea=6A %W0U U $V!D:#/5(A07L \[Ii<7%">$GqBc-@I1Tl<0<3Vl8l05D\KPX@.$ J@.$ JYKPX@1  ~qK _zK  _pK_ tLKPX@?  ~qK _zK_zKpK  _xK_ tLK)PX@=  ~qK _zK]rKpK  _xK_ tL@=  ~ _zK]rKpK  _xK_ tLYYY@!76?=6D7D,+*)"  55 +"&'5326654&##77##7##"&54>32366773!2>54&#"7KS6?T)WL% bH $V8AP$Ea=6A %W0[ 1Q0B|j!D:#/5(A0Q2V5HB<2c-@\[Ii<7%">$@/U=MwE/1Tl<0<3Vl8l0,;>H=64-;.;$#&$ +'667#7##"&54>32366773!3>32##%2>54&#"#32654&#"f; $V8AP$Ea=6A %W0UL%;?)29aUU`!D:#/5(A07L:+,1X c-@\[Ii<7%">$Gq4H%;(A?)h1Tl<0<3Vl8ll! .,$7@ JK PX@ n_rK ]pLKPX@_rK ]pL@*_zK]rK ]pLYY@'%10%7'7 $# +3"&547#?336632&&#"#'3254&'&&547#6J ;SZ>4!1S@,,2#5"6q_y&49:<4A '(&ozF ) '(5%QJHJ' D3)" ! ,f+7@!" JK PX@3p_qK ]rK _xK_ tLKPX@4~_qK ]rK _xK_ tL@2~g ]rK _xK_ tLYY@-,10,7-7&$ ++ +"&'53277#"&547#?3376632&&#"267# ? +6J =SZ>4 HL" "* M,)S>Jr9 4A '#(&oz4PaI:8S^. ! ,<H@$%. F J:IK PX@*n  g_rK _ xLKPX@)  g_rK _ xL@4  g_zK]rK _ xLYY@#>=DB=H>H8620)'"  << +"&547#?33#3267&&54>32&&#"6632#"&'%2654&#"6J =SZ>4>K.'Ih@#E7 +F3%Q/B>fS8P:W723  J 1 4A '#(&ozC ! "!Hb9 I ,J]1 $I/HH'!)I)(JKPX@  3 2J@  3 2JYKPX@*_qK _rK pK_ tLKPX@5_qK _zK ]rK pK_ tL@3g _zK ]rK pK_ tLYY@GFED@>750.&$ JJ +"&'53267#?>32&&#"33>32#"&'53276654&#"##0 $( n]d 0F14"'. 3C+=JVIK <V"%"NE1Xd{pLJ;7 %!0EM C ,>3c2"D@+lJXJc!$/jXS^[*KPX@J@JYKPX@qK_zK_xLK)PX@ qK_zKpK_xL@ _zKpK_xLYY@ ** +"&'#332654&'&&54632&&#"ZHi- XX#cF;>&49:cS1SA++3#5"6r (z!.&' D3DTF ) '(5%QT: RK)PX@qK]rK]pL@]rK]pLY@  +33!3%#X0U MGqB<O I@F J ]oK] pL    +37373#'37373#'|CDxHGCDxHGzPPB?@<~e]oK pL  +7!#7#7!#7#11X 11X 闗闗1"0wKPX@ J@ JYKPX@_zK_xKtL@ rK_zK_xKtLY@00)%+) +7>1##"&546776654&#"56632326677350 3C,=I$ )0@% !%"OD1W5)2"DA(  C 1=+ %0jX1"AKPX@  >?J@  >?JYKPX@!_zK_xK_tL@%rK_zK_xK_tLY@<:43/-$"AA +"&54677667##"&546776654&#"56632326677332670?3C,=I$ )0@% !%"OD1W )1= A<2"DA(  C 1=+ %0jX  C GGK5)&f 3+GG05)&f 3+GM5)&f 3+GLgGU5)&f 3+ %aGC5)&f 3+ %aGE5)&f 3+GaGK5)&f 3+Z$aGZ5)&f 3+aG\5)&f 3+<<<paD 0dD@%gW_O  +D72654Ha % $2LD2#35*9;v? *dD@gW_O +D"&5463"3$3L8 (?5)8=2#`S6dD@+  JW_O%% +D7654&#"'6632x /<">?IL XM  2>,4H4\e8dD@-  JW_O%& +D7&&54632&&#" 1,RG"6,(++/5@%;F1 * - Tte 3+t!e 3+n"d 'dD@Jt +D73#'nhu'YO"뼼o"e / /3+nT&dD@U]M +D73n#O#Ts^Gv^6C46V 3+mL` 3+4CT ְ3+4vS ְ3+ ,dD@!JU]M +D'37:v;苋o dDt +D'3: 3+0 3+~  3+*~  3+  3+!L dD@U]M +D3#, L<q;W 0+'7'77'!H.3/H"I/4.;*<;+<<+;<*;GaG-5)&f 3+GGO5)&f 3+8AgGV5)&f 3+aG[5)&f 3+lnG_5)&f 3+NT,dD@!U]M +D!#5!nBPNT0dD@%Ue]M +D!#5353BBPNT0dD@%Ue]M +D!#533BFB(PNT0dD@%Ue]M +D!5#533BBPMS,dD@!U^N +D3533MBBnPNT,dD@!U^N +D733NBĦjBNT0dD@%Ue]M +D733#NBĦjB9KU ۰3+pW%5 53+<8'dD@Jt +D'373K`K:vRކ 'dD@Jt +D73#'D0`K9w܄0+'7% k1kH@=0+77'7D H@=Bk1MC 3+M : 3+.R 3+C3QW 3+@ ,Ұ3+&NdDK PX@oU]M@U]MY@  +D53#q5q&NdDK PX@oU]M@U]MY@  +D5#53qq5ENdDK PX@nU^N@U^NY@  +D7533E5qq5-NdDK PX@nU^N@U^NY@  +D75353-q55q0QdDK PX@nU^N@U^NY@  +D53!538M9Хcc0NdDK PX@nU^N@U^NY@  +D53!8ХcBK 1dD@&JH GU]M +D'57!!O1;D734",0  6: 48$q Qd"!0"&FNg g3+"&!Ng g3+&1" ->X@U+J gg_?K _6L/."!75.>/>)'!-"-   +"&54676632#"&'663226654&#"2>54&#"_] ,oAS/Q3(K' !a8JK=`@-$$$D54&#"'63233267  *3X2*! -?DFV4*! )@I!eE?3p0'emg*('D JH.u,W'dng*+$B0L"\JK1PX@g_=K6L@g_=LY@"")+37.54>32726654&#"8Y5(TZTs;VWRf0^R?Z8` BhE@zb:BtLkP~FvIW]+GY.e[0!2@/J_@K]:L!!(+7&&54>3226654&&#"4@H"CeB^j>\=2!/O/0(7Q,=hM>zd=o`:uc@1C~X9%K}K>D`uY@  JK1PX@g_=K6L@g_=LY@ %%%+!7&&546632&&#"33%h|Zi:S$$C+LvCYl+/zkcXJCtHSS0:"*4@1Jc_@L**+"&'532654&'.54>32&&#"%43!66 5 E1#GiF%B8"/G/79:>h H - $ +J:  &67 iH $<-%=,H4-C D 1,&G7F8&0!EU!O@  JK1PX@_=K6L@_=LY@ %/+!667'754&''7&&#"'6632:-G~' '9%0Q&*cAzG=IXKAf1wAxF xd* @  H:L+>7'74&''7&&'5-L0 &{DvVYMDQJCPGPDOL[R̀u Y",KPX@)*J@)*JYKPX@_@K_6LK1PX@ 8K_@K6K_6L@#~8K_@K_6LYY@'%,,+"&5467#>54&#"'632332678BX2*! %?DFV4*! # EI3p0'emg*('CJH.u,W'dng*+$E!'6<@94J_@K_6K:L)(1/(6)6''&-+654&'.5476632#"&'#2>54&#"-3F$|Zc#DeC2I-%J/B/F.92?T3@ #OFMukhE}_7*  .1 '# //Na3J>\_&0"F MH_0" !)Hx&(LO JK1PX@~5K6L@~5LY@ +3333#667###(n~!|Z]  I \64g h9NZ JK1PX@~8K6K:L@~|8K:LY@ +33#667#'_ffqV@ FZ s 2?C !*J@G(J e_@K _6K:L%#**&$ +73>32#"&'3##7%2>54&#"SNU 4`N\c>aC1E W,B,38BC'32&&#"3267fh'MqJ(I:3M5C$#Co\C|b:F 0O`1BD H  '@$]rK]pL ! +332#'326654&##qfxRi.5Mj8RF9rdfLG?pIII 7@4e]rK]pL ! +37#73732#'326654&##3#2JJ0fxRi.5Mj8RF9!ooHrdfLG?pIIIH /@,e]rK]pL  +3!#3#3q/ $HGH(J@G"Jg_zK_xL (( +"'732654&##732654&#"56632dM5E"2>7)<#Ob4+%Q/+P*_WRM+(l79+)&&J6/$&P R::J  ;)IM:)@&crKpL  +33"&54632qXqN#'#6+@(JrK_xL  +"&'532673B$ !+ TXRR G #)xPJ%@" JrKpL +3366773#'qX3 !jer.,"[ *@' JrK^pL  +37'7373$J32'26654&#"bj FpO?[1$InD9W1:82I0<w`54&#"56632(I:3M5C$"D+fh'MqF 0O`1BD H o\C|b:4"[R<&@ &3+.5ZF8@ 3+ v :&@ &3+,@!p 3+ #/@@= JhrK_xL%$+)$/%/ ## +"&5467&&546773326773'2654&#"RbF@WQ16 X 4+ '>l@DK3,CK5WICY/  HH G<.HH2I>+A\1GJ>).F<+25 !@_zL%# +>32#654&&#"5 BnL^j[0(.G0  G}No`"%(9%5[90 $@!_xL  +"&5467332673]kZ=7<][)BZo_$$&>Dka5cO. +@(g]rKpL %! +332##32654##qVQEqC++:$@U`1N?GT%6@I 8@5Je]rKpL & +#7&&54633#7#37#"#0xhqX-H<&==C:7RW*6S$ ;@8JgrK^pL    +3"&5467'3373'37#"TUH?]aQO-Xq<&;!<'1L>BSG.'$&:!@]rKpL +3#7!#qbbHH0:*$@!rK`xL +"&5467332673YbFYI90>C IXI 8_ TF I +1I9Y:X2 BX8@ ܰ3+@ ߰3+zP@ 3+< !@JrKpL  +3336673FY&`2.AH!'@$JrKpL!! +333667336673#'&&7#X_  O  xhk  vEC,EG#137 %@"]rK]pL  +#7#7!3 Kb ;I@EX*pKPX@ J@ JYKPX@]rK_xL@]rKpK_xLY@  +"'53267667!##*: :pZb&# !F E /?Cp7~n QDG$5)&f 3+gG5)&f 3+PG%5)&f 3+B&fK%PX@" e]K] L@ g e] LY@&$ ! +7#737323##'32654&##32654&##P.< =*x@J-> IeM"L+>'-BMR7<(1H,/36, #BC&'-*(PG'5)&f 3+PG(5)&f 3+8Gm5)&f 3+dG*5)&f 3+PG+5)&f 3+(-G,5)&f 3+G-5)&f 3+PG.5)&f 3+PFG/5)&f 3+OZG05)&f 3+OG15)&f 3+O>JK%PX@KL@LY@ +33#7667'Ob534Y?.4;DAV8CLMAn<=%E(&I3#%0Y `Q$)"454#" 6C!B 4:+ X  5:+  R=BQ$D`D(B/U!E:#2 7%Rz >B:k>B%G!+;\ZIi=I3Vl8l1Ul;0<00?@-  JKPX@1hqK_oK _zK  _ xLK)PX@5hqK_oK _zK pK  _ xL@5h_oK _zK pK  _ xLYY@#21:81?2?,+)'%$"  00 +"&54>3236677&#"#66327332673#"'#7#'2>54&#"AP$Ea=6A  4:+  W  5:+ |H $V!D:#/5(A0 \[Ii<7%":$5 >B:k>Bc-@I1Tl<0<3Vl8l<@"#. JKPX@3 g  g_qK ]rK_ tL@1g g  g ]rK_ tLY@!86431/-,+*'%  << +"&'53267&#"#66327#?>32&&#"3#32673#"'0 $( C 4:+ ]d 0F14"'. s s(  5:+ :LJ;7; >B%!0EM C ,>3C>BS^"3?M@7 GD:0-*'JKPX@'~| _rK pL@+~|rK _zK pLY@A@54@MAM4?5?33&% +3#67733>323>326673#7&&'#7&&'"7654&!"76654&9($4*H 1@)7<7D)>D'$ 4'Y'.o;.X2I -!%'R@ U!$z%'4}@ /+$ JKPX@#~|_rKpL@'~|rK_zKpLY@)((4)4''$ +#66773>326673#7.'"76654:&(4 S6+N 4C,@J')4 U8'^((FD%2']"'CA$1!GNc3"G@0O0"HN  AL  S@!0?@ $/JKPX@/g h _rK  _xK  t L@3g hrK _zK  _xK  t LY@21971?2?00"(&$" +7&#"#6632336632#"&'#32673#"'2>54#" 4 :, {H #X8AP$Da<6B  59+ (B/U!E:#2| >BHd,A\[Ji<7%9Y>BJ/3Vl8l1Tl<0<"+KPX@JH@JYKPX@$g h_rK  p L@(g hrK_zK  p LY@++"%$%"" +37&#"#6632733>32&#"32673#"'2 4:+ 2H .:& 1M5   5:+ ' >Bc2 O@c4>Bj"'E@BJgg_zK pL''"#%%"" +37&#"#66327>32&&#"32673#"'1 4 :, 1G.+ A  59+ & >BOAI J \>B"7g@d2J~|||_zK_xL/.,+#!77 +"&'532654&'&#"#667&54632&&#"26731IP*;>%4.+4 6% cS1S@,,2"6' #( 5 4#q Q.&- 8?$DTF ) ) #6? QTl5@(2 3 JK PX@/n g  g]rK _ xL@. g  g]rK _ xLY@0.'%#"  55 +"&5477&#"#66327#?33#32673#"'32676J  4 :, SZ>4(  59+" 2 4A 'T >B(&ozC>B# ! C $I@F!Jgg]rK ]  p L$$"#"$ +#77&&#"#66327#7!32673#"&'3  4<.!}E 5>-# < >B BG>B B)$3{@ JKPX@ g_zK_xL@$g_zKpK_xLY@&%-+%3&3 $$ +"&'##6632&&#"136632'2>54#" 6A!Cz{`1SY+>O  #V8AQ$EaD(B0U"D9"- 8%S7q`Q Jg]rK_tL %%  +"&54667'57!7!'26654&#"doCzRX  i2.AfC?M#@5AQ%Cj[UEBB@N%a>4eR1I>c8=?>b5?AFDZ@=7 C> JK PX@-p   qK_rK ] pLKPX@.~   qK_rK ] pLKPX@2~  qK_rK pK _ x LK)PX@=~  qK_zK]rK pK _ x L@:  _zK]rK pK _ x LYYYY@DDB@;965%# +7&547#?33#336632#654&#"#3267#"'f =SZ>4>QX+ C">IFXG !%#ND1X= " 2(JKk/ '#(&ozC !|# ED(P-!%/jX"C M@3@0JfrKpL +#?#737'733# M&FGG LKL&F 4G44G4=@:JfrK_xL  +"&54677#73733#32674GGG-X.\\  3 4A%DGGG  C J!'1@  JKPX@*   f _rK _xK tL@.   frK _zK _xK tLY@ )(! -,(1)1$# '!'#$ +#7373366323##"&'#"36542667!gDD.H #X8AP:4DeA6B1"-[(@/ 2Fd,A\[FIuE7%9VClg2T4''0<>"A@> frK _ xL""  +"&5467#73733733#'2677#Y_CC.Y/.X.BA 8_B>C 3 YF/FF?:X2GI9:#,,3E$-C@@J  e]rK _xL,+)'$$# +'73667#73!54&'73#3##"&5473267! 1 1'`4F+&q!5+ CoMeiX==<_F-NIEQ;4REIP+FEpBy_">NS[:&5KPX@ J@ JYKPX@$cqK_zK `xLK)PX@(cqK_zKpK `xL@(c_zKpK `xLYY@('/-'5(5 && +"&'53277#"&'##3366322>54#" " 0 6C!BX& $U8BQ85 =:(B/U!E:#2I6B7%R"B*,A\Z\4?;3Vl8l1Ul;0<0:U&5KPX@ J@ JYKPX@% cqK_zK _pLK)PX@0~ cqK_zKpK _xL@0~ c_zKpK _xLYY@('0.'5(5#"!  && +"&'53277#7##"&54>3236677332>54&#"U" 0 $ $V8AP$Ea=6A %W/ $Q?;1Tl<0<3Vl8l5@+  *JKPX@1  e  g_qK]rK_ tL@/g  e  g]rK_ tLY@21/-(&#"!  55 +"&'53267#?>32&&#"3#3#"&'53277#0 $( n]d 0F14"'. s sI*<4" 0 LJ;7 %!0EM C ,>3C?;I6ytS^"5D@ +*JKPX@2fg _zK  _xK_ tL@6fgrK _zK  _xK_ tLY@!76?=6D7D21/-(&#"! 55 +"&'532677>1##"&54>323733#"&'53277#2>54&#"1SY+>O  #V8AQ$Ea=6A!CY* <5" 0 {;"D9"-5(B0Q323>323~" 0 /H!#!H?3XG # J@1XrH 1@)7<7D)>D6) =I6DP!$0fPP-!%/jXc2"@77#D@*?;: "+}@JKPX@"~c_rKpL@&~crK_zKpLY@('! ++ +"&'53277#6654&#"#33>323W" 0 0G"%"ND1XrH 3C+>I7+ <I6DP!$/jXc2"D@/?;!%4@ JKPX@%g_rK _xKtL@)grK_zK _xKtLY@'&.,&4'4%%#%($ +336632#"&'53277#"&'#2>54#"H #X8AP93 <5" 0  6B1(B/U!E:#2d,A\[\4?;I6C 7%9/3Vl8l1Tl<0<:""KPX@JH@JYKPX@!~c_rKpL@%~crK_zKpLY@ "" +"&'53277#33>32&#"3" 0 1rH .:& 2N4 %, =I6Dc2 OBf5?;:"6K@H"# Jc_zK_xL'%  66 +"&'53277#"&'532654&'&&54632&&#"" 0 1IP*;>&49:cS1S@,,2#5"6! <I6?Q.&' D3DTF ) '(5%*Ai?;~+@! JKPX@&eg_qK_tL@$geg_tLY@('%# ++ +"&'53276632&&#"3#"&'53277#? ?HL" "* `*<4" 0 MJrPaI:89?;I6ytS^0:=@:JcrK^pL  +"&'53277#33>733" 0 >X  ^v <I6DF=@@'.?;:H@E J I~crKpL  +"&'53277#'#3733" 0 [ftYSfZ2 =I6DǕ?;:=@:Jc]rK]pL  +"&'53277!7#7!3" 0  ME <I6D<BGq?;0:&"(:KPX@ %&J@ %&JYKPX@! d_zK _pL@0~ drK_zKpK _xLY@*)42):*:#! (( +"&54677#7##"&54>323733326726676654&#"/9! #[8AP'F`:5B Cc-" "$H94,'B2,//  Ac,A]ZKg<8%S1I6[:2/<1Ul;660:&"x07F@#$ 45JKPX@+_qK_zK _xK_tL@)g_zK _xK_tLY@98A?8F9F20(&! 77 +"&5477667##"&54>32366776632&&#"32672>54&#"0?  $V8AP$Ea=6A 32##32673267326654&#".: ]e%Fc>LMAn;>&D($" "#%0Y//  <m]@}g>B;5U3 =GI1)!Y:!=]@Z2:;Jgc_zK_xL860.)'&$  == +"&54677#"&54675&&546632&&#"33#"32673267n.:$YYV=,:[13K @%2F.1=9)D)08.S"#" "//  >N8#?E)Yn'Ih@ " "//  ML=CJddHb9?I:~*n@'(JKPX@c_qK_xL@gc_xLY@%# ** +"&5467732676632&&#"3267.:  + WHL" "* VHC " "//  1APaI:8dP\:I7:&/KPX@ ,-J@ ,-JYKPX@drK`pL@&~drKpK`xLY@*($#"! // +"&54677#7##"&54673326677333267/9$ 3D+=IFYH &"NE1Wc." "//  Ac2"DA(G+ %0jX1I:-S@P"*+J~c]rK_xL(&  -- +"&54677326654&##77#7!#"&'32674.:%Q2)E+=@?fMCs4" "//  4+(#ADAO9VjCIGgG5)&f 3+TagGF5)&f 3+.agG"5)&f 3+QG5)&f 3+4DgG#5)&f 3+UGI5)&f 3+aG)5)&f 3+EgG+5)&f 3+YaG/5)&f 3+<G25)&f 3+VaG35)&f 3+$aG45)&f 3+$aGd5)&f 3+Gg5)&f 3+:G75)&f 3+Gn5)&f 3+GaGi5)&f 3+GIgG;5)&f 3+Y[aG:5)&f 3+gG<5)&f 3+GgG=5)&f 3+GaG>5)&f 3+TeG?5)&f 3+TGB5)&f 3+AgGL5)&f 3+-GM5)&f 3+R"G5)&f 3+:aGS5)&f 3+OaGT5)&f 3+[aG5)&f 3+_gGU5)&f 3+EaGV5)&f 3++RaG]5)&f 3++RaGZ5)&f 3++naG[5)&f 3+ ZaG\5)&f 3+TG5)&f 3+)M&%N3+&EN)QM&% lQ&E I)mM&%L 3+m&EL 3+Hx&&'zv#3+0&F'zv)|&'N3+0U&GN)Q|&' k0QU&G E)m|&'L 3+0mU&GL 3+)|(?@< J]oK]pK_tL(&!$,! +332#"'53254&'7#'326654&##)Lk )KF R%/GLhJiWUʌmu@!%-=45YM^dna0U,;@ *"!JKPX@'qK_zK _xK_tLK)PX@+qK_zKpK _xK_tL@+_zKpK _xK_tLYY@.-64-;.;&$  ,, +"&54>32366773#7##"'53254&'772>54&#"AP$Ea=6A %WH &))KF R%+!D:#/5(A0 \[Ii<7%">$c'P!%-=45PI1Tl<0<3Vl8l)3|&'J հ3+08U&GJ ڰ3+)*#&(:3+0q&H)*#&(:3+0q&H8*&( #:"&HJ ܰ3+>*&(Q 3+ E"&HQ 3+)*&('Mwz3+0&H'zM?)*&)N3+&IN3+HW&*L3+'&JLe*&+N3+ &KNN3+*Q&+ ~Q &K C*&+jf3+ &Kj3+&+z- &Kz*C&+M 3+5 &KM װ3+H}&, H&LQ 3+&,3+ng&')&.v3+ &NvO3+)Q&. NQ &N 3)m&.L 3+m &NL 3+)Q&/ 4Q&O )QW&/' 4L3+Q&O' L3+)m&/L 3+m&OL; 3+8&/ 8&O x(L&0N\3+3&PN`(QL&0 Q3"&P (&1N,3+&QN(Q&1 Q%&Q A(m&1L" 3+m%&QL 3+(8&1 X8%&Q H#&23+0 q&R H&23+0R&R H#&23+0q&R H#&23+0q&R )7&3v3+&Sv)7&3N3+&SN)9&5N3+&UN)Q9&5 PQ"&U )Q9W&5' PL3+Q&U' L4)m9&5L 3+m"&ULK 3+&6N3+&VNlQ&6 Q"&V 2&63+&V &63+J&VQ&6'N 3+Q&V&Nl ZM&7N3+,lX&WN@xx3+ZQM&7 ,Ql&W *mM&7L 3+ml&WL 3+8M&7 8l&W OQ&8j ڰ3+)Q&&XjM ڰ3+JH&8 P%H&&X +O8&8 b%8&&X O#&8z3+7&q&X#O&8z3+7&R&X#\&9Q\3+0&YQ\Q&9 /0Q&Y k&:Nq3+9&ZNkQ&: 9Q&Z a&;N3+&[Na&;j 3+&[j\Y&<N3+&\Nv=&=Ja3+&]JQ=&= -Q&] m=&=L 3+m&]L 3+m &KL 3+,R&Wjxx3+9/&ZO/&\O/0&&D &@N3+0;&{0;&{#0;&{0;&{0;&{ 0;&{0LV&{ 0;V&{&$ ΰ3+&$# ΰ3++e&$dM ΰ3++e&$dP ΰ3++e&$dM ΰ3++e'Y$d ΰ3++e$'X$d ΰ3++e$&$dX ΰ3+&n&#u&&&&=x&(N ΰ3+S|&(R# ΰ3+='(Q ΰ3+S'(V ΰ3+='(Q ΰ3+S'(V ΰ3+ & &# & && & OV& 2V&=&+M ΰ3+S&+Q# ΰ3+={'+Q ΰ3+S}'+V ΰ3+={'+Q ΰ3+Su'+V ΰ3+1{$'+P ΰ3+1{$'+P ΰ3+3 &3 &#3?&Y36&S3x&j3f&d3V&g+V&J=&,g ΰ3+S&#,n ΰ3+=f',Q ΰ3+Sh',V ΰ3+=',Q ΰ3+S}',V ΰ3+1~$',P ΰ3+1~$',P ΰ3+0&R0&R#0&R0&R0&R0&R=&2G ΰ3+S&2I# ΰ3+='2Q ΰ3+S'2V ΰ3+=t'2Q ΰ3+Sm'2V ΰ3+@&@&#@&@&@&@&@DV&@'V&R&#< ΰ3+R^'U< ΰ3+Rc'U< ΰ3+1x$'P< ΰ3+0&0&#0&E0&?0&V0&P0V&S0V&6=&Q ΰ3+I &S# ΰ3+='Q ΰ3+S'V ΰ3+='Q ΰ3+S|'V ΰ3+1S$'P ΰ3+1S$'P ΰ3+0;&{3+0;&{" &3+&" &3+ &"3&P3+3@&"k0&R3+0&R"@&3+@&"0&<3+0&"W0$;&{'0$;&{'#0$;&{&0$;&{&0$;&{& 0$;&{&0$LV&{& 0$;V&{&6&$&2 ΰ3+6&$&#2 ΰ3++&$d'M ΰ3++&$d'P ΰ3++&$d'M ΰ3++&$d'Y ΰ3++$&$d'X ΰ3++$&$d'X ΰ3+ &'b &'#b &&b &&b&&b && bOV&& b2V&&b=&+M& ΰ3+S&+Q&# ΰ3+=a'+'Q] ΰ3+Sc'+'V_ ΰ3+=a'+'Q] ΰ3+S['+'VW ΰ3+1a$'+'P] ΰ3+1a$'+'P] ΰ3+0$&'P0$&'#P0$&&EP0$&&?P0$&&VP0$&&PP0$V&&SP0$V&&6P=1&&Q- ΰ3+I3&S&#/ ΰ3+=''Q ΰ3+S''V ΰ3+=''Q ΰ3+S''V ΰ3+1|$''Px ΰ3+1|$''Px ΰ3+0;&{Ma0;&{Lp0$;&{&3+0$;"&{0$;&{&" 0;&{QQ0$;&{&QQ'&$M}3+W&$L3+&$2 ΰ3+&$" ΰ3+6&$2T%dD@Jt)+D7667&&54632KT%!6>$/ Q"T^Q3h-V+QdD@Fg h W _  O! '% +!+"!"! +D63232673#"&&#""&546323"&54632V.) 3R.*  ll## &&b3+ "&b &&"b0&QT0&&QTbCm&(C ΰ3+3h'"(> ΰ3+C&+B ΰ3+3'"+= ΰ3+*&+TdDKPXJKPXJJYYKPX@W_OKPX@U_O@U]MYY@)+D7667&&546327&&'73K!U T%!6>#Q "S TdDKPXJKPXJJYYKPX@ tKPX@t@tYY@)+D7667&&54632756673KY \:T%!6> N% "O#JCV#UdD@JJ~g hW_ O##"!"! +D63232673#"&&#"7667&&54632V.) 3R.* Fll! -13i&M3Z&L,k &[3+3w &g&Q.V&c&,M3+W&,L3+C&,\ ΰ3+3'",p ΰ3+TadDKPXJJYKPX@W]M@U]MY@ %+D&&54632&&'73P',!"-a!U T0%%4!#Q "S TXdDKPX@ J@ JYKPX@ t@tY@ %+D&&5463256673P',!"- \:T0%%4! N% "O#JCV%GdD@<g hW_O%$ "!"! +D63232673#"&&#"&&54632V.) 3R.* +)ll) ) @&MY@&Lh@ &3+@ & & &#@%&QI@*V&\Y&<Mc3+\YW&<Lr3+S'< ΰ3+G'<" ΰ3+S&3R# ΰ3+c !kdDK"PX@UW_O@We_OY@ !!    +D&&'73"&546323"&54632m!U   j#S "U ""c !dD@ JKPX@nW`PK"PX@W`P@#~W`PYY@ !!    +D56673"&546323"&54632;!a="i  j U# Q#""6^ &dD@U]M +D&&'73q V ^#Q "S 0$&&<P3+0$&P0$&&"WP0&Q0$&'QPS'2T ΰ3+8'"2' ΰ3+S&` ΰ3+*&4" ΰ3+&@^ &dD@Jt +D56673@ ];^ N% "O#T dD@ Gt%+D&&54632',!"-T0%%4!{t@U]M +3*{m!@  Ht +'7'77'>RRSSRR>>RQSSQR>d{ 4@1JHU]M  +3'7'7#@ll@y=kk=H+{ 4@1JHU]M  +#'73yAmmA=kk=!;A@U]M +7!;AII&__nk$@!]oL    +&&'73#&&'73DUU65 ;965 ;9{Z$@!U]M +3#迅'H,{Z$@!U]M +#53'!{t&@#U]M +#53#__b{t UKPX@e]rL@eU]MY@  +#53#3#__b'&{t UKPX@e]rL@eU]MY@  +#535#53#__b&'Du&Re;q[ #/K)PX@+ g_wK _rK_ xL@) g g_wK_ xLY@#%$ +)$/%/##    +"&54632"&54632"&54632"&54632$$%%$$%%$$%%$$%%M $%%$ $&&$ $%%$ $&&$ {t\KPX@e]rL@"eU]MY@ +#535#53#3#______b&''&{t WKPX@e]rL@eU]MY@  +#53#35#__bb{u@Jt +'3``}{u@Ht +#7#`uu`b{u @ Ht +'77'`uu`>>>sYkkY777{t YKPX@e]rL@!eU]MY@  +#535#533#_____b&'&eY1@.gW_O  +"&54>32'2>54#"9>+G3y-G,*8)ML-gZ:7lY5>,IV)Q*ER),/jS'K@H  JggW_O" ''  +"&546632&&#"36632'2654&#"5C3kT# !32&&#"37!#3#30ZZ"@^<$=3(<)36+"VYAtZ4 D -J[-95BBC9S(19y@30'$JK-PX@hgqL@%hW_OY@.+((A +7&5466773623273&'667##7&&'7&&#"'9=F/KPX@  ,!-J@   ,!-JYKPX@g_wK`xL@&~g_wK`xLY@*)%# // +"&54>32&&#"336632&&#"267"nv8UsJ]F$=)EeB &&I< @/  (8" 'G"$I @v]6(JCoC@[\M"3J0N, N35@ ' JK PX@(n_rK pK_rLKPX@'_rK pK_rL@$_zK pK]rLYY@55&&#% +333>32736632#6654&#"#7#7654&#"rH 1@)-9 F\+>DEYH!#!H?3X#G # J@1c2",(̏ D@*P!$0fP-!%/jXD#'+Y@VJf   eoK  p L+*'&%$#"!  +3#737#73733733#3###3'#3'#37#37#!6HHHH4f!o4N4HHHH6e"m6a'0W ;=Y"(@R@@R@yRRRt! =@- . JKPX@+e]oK _zK]  pL@/e]oK _zK pK_ xLY@20+)== ! +332##326654&##"&'532654&'&&54632&&#"KF?\3Y>N=0B!1/7>+AD$24(,*XF*F3""(**`ʵIv's,G)=0zQ.&+ @3DTE ) )&3%LY"&*.14h@e"J  f   eoK p L4310.-,+*)('&%$#!  +3#737#73733733733#3###3737#37#37#7#7#I QF9/ Nb_T cVOZ-7CM]Y i`%4MsT9x7P0!."@R@@R@әRRRRRٕ2@/U]oK pL +3#7333733###)GQPBYClʺbC<NB:!BN1+M2@/ J]oKpL +37'77'77#7!#77!sr/"xw.G5caG5bOOK5faJ5f/<@: *JKPX@:~  g_wK` pK _ pK tL@7~  g_wK^ pK _xK tLY@10750<1<//(&!%&! +33326654&&#"'6632#6632#"&'#2654&#".{Vk eG:lI+`$$n:dQgtYR]QPL*XF1  -C$"(4 (B ZbEg9GL^ePcR>.[=5-,D;#(384''3C@@" J_wKpK_tL/-'' +"&'5326654&''#7&&54632>54#"" !"( /UP0n \G5>!4=Q5$,3J)B%0bAć{Kc.}rB5,ZYS#]0`rL"SZ,9Ta#@#Y!'-T@Q e e  g ]oK p L-,*('&#"!! +3#737#737323#3###3&##3667#3267#$OP PP P=L'I < < E#a91y j@- -/5Zw6Y6&@(636LB773&&'3#'2677#_j3^PA5P&""L,9L8e9 yGn?;&=.vPLm^}L$$NF5 feEe U"J@GJ f   eoK  p L"!  +#7#737#7333#3##'#3&&'3'#9E [,u _! u Y DX~`*g @R@ @R@-Z&&WR)5^@[2 3 Je   e_wK _ xL0.)('&#"!  55 +"&5467#73667!7!654&#"'66323#3!3267_r /Z"^7h :2&G#'^1Yf0WR6B:4U%"[ ZS/@&@ 7*1L`I2&@'@).6NHx$q@ JK-PX@ oK]qK`xL@goK`xLY@ +7&&54>773&&'667'`j,XZAO;$:%z&H#%K2 y?\=APKqNV%% I  M G6 Hk|>Lc\D>@;   geW_O"" +373267#73&&##7!#3# 1RX FI$  #nf 4dQF082@46@@ 7'@(I0j6k pp3+1&1:X@U ~gge W _ O'':842'1'10.*(&&  +".54>32'2>54.#"'32##532654&##Pc66cPLe96cP@pV0.SqDZP.Sr>RLV>RF',)+E 6cPPc66cPPc65.UrEArV1Q[ArV1_EDCL%*(#! :@+ , JK PX@:   ~ ~f  gW_ OK PX@3   ~f  gW_  O@:   ~ ~f  gW_ OYY@$0.)'::   +333#'#73'&&5"&'732654&'&&54632&&#"XN뇿@.< n6QN   45&*"'C=7-!&%T6rXbb^  ; .0;5 *#72 .@+eU]M +#737#7373%/XrHHO'?'{uma3+a3++)'|'t~u`~3+`3+"!<@9f eoK ]  p L +37#737#7333#3#!)/PPPP7Y8GYGGYGP `K)PX@ f eqK  p L@ f e  p LY@ +37#737#7333#3#5EEEEB/ >BP)7=@:g]oK]rK pL$! +3#73732##32654&##3#)`OP&sc@;K>`qCDLNgSybRY;5fN9'I@F Je]oKpK_tL'%!  +"&546732##326732654&##1EQavbfuO  &:Nd[ECL1; Mr' LcWE=00/'3KPX@1 J@1 JYKPX@"qK_zK_xLK)PX@*qKrK_zKpK_xL@*rK_zKpK_xLYY@)($"  +"'#7&&54>3273373#7#'&#"26676654' dFo#'F`:#sE  CrF #[o 'B2T$H9 P;Kg<Sc,A0u1Ul6[:2*0"%@ $ JK PX@*pqK ]rK_ xLK)PX@+~qK ]rK_ xL@( ]rK_ xLYY@###%#% "" +"&'#&547#?33733#32677,nE =SZ>4ApEp" 2 L  '#(&ozCC ߘ*DF"`JK)PX@aqK_zKpL@a_zKpLY@""(% +7#654&#"#33>323)QG !%"OC1XX+4C+>I6P8P-!%/jXA 2"ED()D.@+ JaoKpL +7##3733( SlʇG8Z=BF W JK)PX@aqKrKpL@arKpLY@ +7#'#3333L) qH(YYAhlI89PWF= +@(]oK]pL  +7!7!7!!3) CQ9F4PGF +@(]rK]pL  +7!7#7!!) ME6<BGqH) JKPX@_wK_xLKPX@oK_wK_xL@!oK_wKpK_xLYY@" ))  +"&&54>32373#7#'266776654&#"1Hh9,XZJZ$IG#_9E\6  XIDc?$F C{RVOC,d6c/>NAd5k4FREp@:Z40"O@ JKPX@_rKpL@rK_zKpLY@ #, +33366776632&#"n>X  %}1($ 63S -& @6\k,W@ 'JK(PX@]oKpL@oK_wKpLY@,,$+ +333667336676632&#"#&&5#X([ 8/ #  ^ M)X('e,^/f%(Z+W,2G%!H"?179 "-W@ 'JKPX@]rKpL@rK_zKpLY@--$+ +3336673366776632&#"#&&7#OV _ &T5#!   m6[L5/736654&#"}%/!EA78V<  !! ^Y -C.GM=,A[B<@>(Q 8&5! )#@ foKpL +33!!)Y@FO#@ frKpL +333#rX03J0w!%,@)J_zKxL#! +"&54676632'>54&#"!rSQ8DA2APNHI$P32P^_VBmBK" }""Km$@!W_O+663"RwbGKa[G8=TK$@!W_O+&HC rpK7>G_]_\ .@+JW_O %"+6632&&#"!oD3U)*V57C_A? C $L` 0@-JW_O   +"&'7326734U(+U48B6'k` C "C=0;j&{X0;j&{W0;j&{W0;j&{W0;&{N0;&{N0;&{N0;&{N3Tj&3j&3Sj&3tj&3f&3&3f&3v&@j&P@j&O@j&O@j&O@&F@#&F@&F@&F3k&3k&3x&3x&@&F@&F@&F@&F)C&g@JKPX@c_#K$L@c#K_*K$LY@&&+"&'732676654&#"#336632^+ $+B b7?AeEOYJ"sI[c anM1=#7=K|Gu:F]\$+3eX(C Q-| JKPX@*~_#K_#K_+L@(~_*K]#K_+LY@%# --+"&54673326776654&#"#3366324spWHG\\-7?AfEXKJ"sI[c .Gw g_)&8@\Y#7=JzGbu:F]\$+Nr=VjKPXJKPXJJYYKPX@gU^NKPX@!gU^N@(~eU^NYY@) +7667&&546327&&'737!K!U  %!6>#Q "S lGGVjKPXJKPXJJYYKPX@U^NKPX@#U^N@'U^NYY@) +7667&&546327566737!KY \: %!6> O$ "O#lGGVjrKPXJJYKPX@eU^N@eU^NY@%+&&54632&&'737!',!"-a!U  0%%4!#Q "S lGGVj|KPX@ J@ JYKPX@U^N@!U^NY@%+&&54632566737! ',!"- \: 0%%4! N% "O#lGG^'NYv^J&NjK?j3+mR ^KPX@g]oL@gU]MY@     +"&546323"&546327!  ""GG]R ,G@D  g c_oL ,,*(&$"!     +"&546323"&5463266323273#"&&#"  6.+$%3A))$ ""5=14>]q D@AJ d_oL    +5667366323273#"&&#"4e196.+$%3A))$  <" ..5=14>mq [JKPX@]oL@U^NY@  +&&'537!a9[ $ K !C! sGGmq [JKPX@]oL@U^NY@    +566737!4e19  F" 33rGGY)n JK$PX@ _oL@!W` PY@%#)) +&&'536673"&546323"&546321 25(>985 &P 0/ 59""YD^K$PX@e_oL@eW_OY@  +7!"&546323"&54632!  GG""]D;@8e c_oL  +7!66323273#"&&#"=5 7.*$%3A))% GG5=14>^D*@'e_oL  +7!"&54632$ .$GG'-# /@,eW_O  +7!"&54632 .$GG'-#Z #/@ JK&PX@)  h  _ 5L@/  h W `  PY@&%$ +)$/%/##   +56673"&5332673"&546323"&54632(_A" B94$,..7T A 0 5p9DH5w##Z #/@ JK&PX@*~ e g  _ 5L@0~ e g W `  PY@&%$ +)$/%/##   +&&'53"&5332673"&546323"&546323)W>B94$,..7T A5 1 p=@H5w##Y %JK$PX@# f  _5L@) fW_  OY@" !%%  +566737!"&546323"&54632 (_A"  A 0 5eGG""Y %JK$PX@!e e  _5L@'e eW_  OY@" !%%  +&&'537!"&546323"&546323)W  A5 1 eGG""O(|KPX@ J@ JYKPX@d5L@d5LY@&%#!((% +&&5463256673"&'332673',!"- \:I;I6+8N0%%4! N% "O#;=7AO(rKPXJJYKPX@ed5L@ed5LY@&%#!((% +&&54632&&'73"&'332673 ',!"-a!U ;I6+8N0%%4!#Q "S ;=7AO'KPXJKPXJJYYKPX@  d5LKPX@!  d5L@%  d5LYY@%$" '') +7667&&54632756673"&'332673KY \:\;I6+8N%!6> N% "O#;=7AO'KPXJKPXJJYYKPX@ g d5LKPX@ g d5L@&~ e d5LYY@%$" '') +7667&&546327&&'73"&'332673K!U ;I6+8N%!6>#Q "S ;=7A%KPX@J@JIYKPX@]#K]$L@]#K$K_+LY@%%+"&'532667>733### -)%&%ab^fb#a "!4L NA<.x<5z1uyo+?\1!'@ JK"PX@_%K]$LK-PX@_%K$K_+L@!%K_%K$K_+LYY@!''+"&'532667>3273#'#'&&#"  .)*5N:$Rf{Y[fU *2*5IL*\KCbA '^USr;*O:@7  Jg]#K$L"!+33273###32654&##*tbb^Q@;K>`qCDLgSZCbRY;5!,@  JKPX@]%K _$K'LKPX@#]%K$K _+K'L@'%K_,K$K _+K'LYY@&$,,$$ +33663273#'#"&'#2>54#"H #U;BOfYaD\96B1(B/U!E:#2d,AXV=^67%9/3Vl8l1Tl<0<S J@GJe e ]#K] $L  ' +#&&54663!!3!!!#3#"'(6JzI/7?lG9W2P/BFJ@Sd-ONO(t ?66C"7AJ@!  45JKPX@+g   g  _%K_ +LKPX@5g   g _%K _%K_ +L@3g   g _,K ]%K_ +LYY@#CBFDBJCJA?:820+)$"  77+"&&55#"#"&'53267667&&54633632##3267326654&#"37#"=S+E/,%3'  !*"0-jj :ILMAn<=%N&I#%yX%t5:: 5[9..(8F#. 2 B+Ia3=B;5U3 @GK91)!3,-#*-@*  J#K$L+337'773'#*YJL9FklM:FfJi+_nh+_b-@*  J%K$L+337'773'#qW7;06Jn=08Ui8L%EML'HU ;KPX@1#J"I@1#J"IYKPX@)g]#K_$K_ 'LK1PX@-g]#K$K_+K_ 'L@*g c]#K$K_+LYY@530/'% ;; +"&'532>54&#"###"&'532667>7!6632A)?:!326632!.-8O+<7 0Xe *2*5I;  -**5N:"@1!3R1@c R CuJDM'^USr;L*\KCbA 1aHBz_7*)@ JK1PX@(f  g#K$K_ 'L@%f  g c#K$LY@#!)) +"&'532>54&#"#!#3!36632b(@;!323(KG"%"ND1XrH 3C+>I6L8P!$/jXc2"D@/(E\4@1Jga#K$L#%+7#654&#"#366323(V:)-4Y0IZZ=$`7PR)R:"$HC F"6@3Ja_,K$L""(%+7#654&#"#33>323(KG !%"OC1XX+4C+>I4J8P-!%/jXA 2"ED(cV EKPX@o]#L@]#LY@ +'7!#'##'#: [# [#cT T2222 ?@< J~oK`xL  +"&'??37726673%6Ejji j'Z 32h0Q!!S)/S2HH  74UbbXbHxW[fGWCx R#G54?A%'cU2LvB\J ^NHk;W$X ʰ3+>j&3@0J H_rK_xL&& +"&&54667326654&#"76632.Pk5[]:B6C^2:2) *6Q,)Qv AsM~0CД3Q0GsCAFF 7\9Dy^6",@) JoK`xL  +"&5466736673'32667'w15+]Lz 9OK-2>9&XK*=>CC=3/V6a*8@?C<1-T6T %@"c]oL  +"&546633#"33(dp=uVgV_ZQD  e\KsAPdTAE2*@>@;JfcoKpL  +"&'53267!#3!3G'&,=CFYY@:@XcL:G>.HlfZ&7 3+!F$H@E !"J~_wK_xL $$ +"&&546675'7732&&'#"3267 Qg0AtK ;\5)+B+ +i|HF2i/.e 1R2M_1 9x&=\DHT4<R;@8JeoK_xL  +"&'532677!7337667#   ' wepL    M(//QWV!:u$ ," +K(PX@J@JYK(PX@%~ foK_ xL@)~ foK pK_xLY@!!!+!+'&%# +7733##"&'532677'37667#7>73weWLG   '    ' W6QMN&WVM(//N:u$ , 7: %T"&$$#.*JKPX@!f_oK _xLKPX@%foK_wK _xL@)foK_wKpK _xLYY@%$##&# +#36632#"&'#%2>54&#"%31'&&'#9^-gy-YWu tg<^B#ZN<`D$\ &ʸWl]}H|lE?)T} *I@F& JfoKpK_tL"!    +"&'532677'##33>733'&&'# ""6*tb^0 cS)Y(N)-Nd ME;=LJ/M#&O-))3@0 JfoKpL +3#73733#73#)tTTY__'>lʩbS<&OUUOBpZ=)-@*  JoKpL +33737#''7')YJ>l;stWbArt4S<Bƌ?6@ͣ?6@=);@8 JfoKpL +3#73733#737#''7')tTTY__'>l;stWbArt4S<&OUUOBƌ?6@ͣ?6@=x (@%JoK^pL  +37137!Xa 323##"&547"!654&2667!+^\y0)Ya`>cDZ@cBb\JF\VFaY 326632#"&'2654&#"2>54&#"Q1^TI[ D;AJ!G:$0YL.3"%(;(<^B#ZN<`D$\ \I()#.K6.V8 WsBD/#*`qCDLuK gSyWKubRY;5z#8@5~g]oKpL#!$!%$! +3#"#&54663332##32654&##l;,,I#OALtb@;K>`qCDL9) ,O1hgSybRY;5j,5KPX@ JKPX@ J@ JYYKPX@g_wK pLKPX@'g_wK_wK pL@%g_wK]oK pLYY@53/-,,$!*%*! +!#"&546776654#"566323332##32654&##;NP'  60MLtb@;K>`qCDL?E,E -AD3 @ChgSybRY;5@V,<@9J_wK_xL&$,,&% +'7'"#"&54>327#''2>54&#"1h(1^Ty:pO!pdAr#V=_A"ZN<`D$\5)<\Ig,-4(V432%66544#''2>54&#"(.1^Ty:pO>-#%8BCLLr$U=_A"ZN<`D$\'OE\Ig(&8&!)704L0e654&#"'66323733##7 AR%'' @'+.V=FW$M=VTTV<:K>% ( ;%*K=0MO4tKL@  JKPX@oKpL@oKoKpKpLY@  +73336673#'|4X"5&c_R ]N)T$$O/6k0?@<& JoKpK_tL,+"!00 +"&'5326677&&5##33667336673~ !%%) \X([ _4JN "$T!K?17M)X('e,^/f%&Z,(E+)pK PX@(fgoK ]rK pL@&f  egoK pLY@$! +3#73733#32##732654&##)PO Y cb Hsd?(?_rCDM[A..A4fTytRX<4!=@:  fgeoK pL$! +37#73332##3#732654&##)PO|YHsd? bb6?_oCDM@AInfTt{2A@MS<4%@" JoKtL +77'736673M UL VM (o#M 1022#C" @,+1 'D@AJg_wK_xL%#  +"&'732677#7376632##32654&#"& $*71 POANsY42k3/41 L9CJ4Lb@AUVg^7%!27R*9@6Jg_wK_xL**&%%) +52>54&&#"3267#"&54>32}MkE'2+1B"21"3OS=]?al1[ K/N]_P.K,7W28@A jO4cO/~p9lBH!QK-PX@]oK_xL@g_xLY@!!  +"&54667#7!2'2>54&#"Q#G7Gy-YT<^B#ZN<`D$\ Jy)N]}HO7&&5467#7!#"'326654&';^5*FW-x05!$8?BwB>.E'*%2]< -U;=\B+ .,JJ%"%(jBSzD=>5Z81C#5[+0Q ʰ3+`/ ʰ3+;*e@ JKPX@_oK_xL@ oK_wK_xLY@***%*$ +3366323267#"&54676654#"E&kCRUA0  )75Bh\k^26NL2 8E:24'eyj1aKPX@ J H@ JYKPX@_oL@oK_wLY@ 3$ +336632&&#"@ ^J %Kpf3=QekK5@2J]oK_xL  +"&&54667#7!#"3267LZq6@lB^j^]VP-.M FtChiNN_nXjNp %@"foKpL  +!!3!3FmQY@:@XM}.6(7-@*JaoKpL +33366733#7##(_ TU?;W+G R$o2PDO$|x%E@B  Je_wK_xL%%%$$$ +73>32&&#"3#3267#"&547/=]|OdJ$C,LpG]R)O&'O8w;LAx^6(JFtDL[i N)E@BJe_wK_xL&%$#  )) +"&54777>32&&#"%32677#73W 3 6fWAb,"&U3S$ 'R@&?.L-d ;7 > UINdVm=o>E7Y4 N )@& JoKpL +37737737#)?[ [KYG-l bD<)>c0<=9T2"-@*"!  JoKpL +3773737#7'#36677(=R RM_t=U9P PQ_|@RyM #  >l>KDO$o20)uB@? Je]oKpL% +3?327##7&&#3267)[X X/= 1RVvbfu>D>NS[  =ܛ >A_'|$3)>3&/=@:*('J_wK_xL" // +"&'5326654&'&'77&&546632&&#"%4O#S6-L.5A  @k@8U&"N)>N() ,5 X:.(9%1>@-B]0L@:).<>(G;knG6@3~e]oKpL%$! +3#"#&546633!3#!",,I$O@z@:@XXFF9* *O3.6ML=-&6{@ JKPX@ g_wK_tL@$goK_wK_tLY@('0.'6(6#" && +"&'532677>1##"&54>323732>54&#"2 !b6 &  ).1),$DQD_A87B(I3`M%?@<Je]oK]pKtL%#,! +32##326654&##32654&## ʹcqXI1BG|O3u,J,JpNVI[ H32##326732654&'3#"&'326654&#"]e%Fc>LMAn;>&D(=2?#' B#%0Y m]@}g>B;5U3 =G$0( ?R 91)!Y""9[@X"0)!3*Jge_zK_xL.,'% 99 +"&'532654&##7326654&#"'663273267#"&'+SS5?K)9FP 8/Je"!(4M@J-# Jg_zK_xL*))4*4! (( +"&546774&#"5663273267#"&''2667JL32&&#"7@ - L@k+/G16"(. Q{YLJ8:h"48EM C ,>+4AYS^$w@JKPX@ e_qK_tL@ge_tLY@!  $$ +"&'53267#737>32&&#"3#@ - v??/G16"(. xLJ8:0HEM C ,>HS^0"1@@= Jg_zK_xL0.*%""  +"&54>32'26654&&#"66;6654&#"]k"CeB^j"Cd=0="0(7Q, = o_>zd=o`=zd=60$qK9%K}K#+/hz{ZFM̠)&f 3+$KPX@ J@ JYKPX@_qK_pLKPX@_qKpK_pLK1PX@gpK_pL@~g_pLYYY@$$ +3"&'7326676654&#"'6632#7#2N4 >"&+GE vH .:OBf5&  EA4 1Q0B|X7KS6?T)WL% q>" 2 4A '#(&oz@/U=MwEQ2V5HB< ! C !$L@I !"Jg_zK_tL $$ +"&&54667'7732&&##"3267F`1L}I ,J =! 7Fi73& %* }fb}~K!   # W7H$1QP6NVPJ>:u$* 9; %W$( )@&e]rKpL  +3!#3#(r-$/GH %7@4J_zK_xL%% +"&'532654&'&&546632&&#"(BA-5:"/,:/T6Q?:*1!$2>l T0+(>5/H($F-& >7OX0R");M@ &#  JKPX@  _zK ` xL@(rK  _zKpK ` xLY@'=<+*GE323736632373#7##"&'#7#'26676654&#"!26676654&#":G'E]60:!8A/.-  CrF  1;&2; (R$E8+&%@1$`$E8+&%@1$ ^XLh;8%SE#,8%Sc2&&Bc1323736632#"&'#7#'26676654&#"%26654&&#":G'E]60:!8H-D\!A`>1<; (R$E8+&%@1$w-L/(!%>- ^XLh;8%SE#,gk=zd=$&Bc1z@ )&  JKPX@ ]rK ` xL@%rK _zKpK ` xLY@.-86->.>('$" ,, +"&54>323733266773#7##"&'#7#'26676654&#":G'E]60:!D<#$JC1WrH )8$&: ; (R$E8+&%@1$ ^XLh;8%S2 '10jXc2"&&Bc1323733>73#5#'26676654&#":G'E]60:!CA  $$ ay(R$E8+&%@1$ ^XLh;8%S4L">;(c132373373#5#'26676654&#"%3>77#:G'E]60:!C,fzay(R$E8+&%@1$ $$ N  ^XLh;8%Sc1;%)4L0(",>@"  JKPX@#]rK _xK_tLKPX@'rK_zK _xK_tL@'rK_zK _xK_tLYY@.-86->.>(',, +"&'5326775##"&54>323733667326676654&#" !)9)(R7:G'E]60:!C@1a[3B'$E8+&%@1$G5-Fc1<^XLh;8%S'=O$}&<"/6\:1/<1Tl;76" _JK)PX@fqKrKpL@frKpLY@ +3#73733#33#'IHYhaqH(\BZZBPW9 P@  JK)PX@qKrKpL@rKpLY@  +33337#''7'YAh,hmKa3UZ'H(PW^C1Fq71:V9 h@ JK)PX@fqKrKpL@frKpLY@ +3#73733#337#''7'IHYh,hmKa3UZ'H(\BZZBPW^C1Fq71:V9i1 ;@ JK)PX@ qKpL@ ]pLY@  +371371tT_NXC_ [!o!0SH HK)PX@fqKpL@fpLY@  +3#73733#E FXF G^@ZZ@<!*E@B e _zK _xL#"&%"*#*!!## +'73>323##"&547%"!654&&267! ;CgD^j93CjH]k k@o` BBsGo_ZF9%k]V>D0#(7KPX@ J@ JYKPX@" g_zK _xL@, g_zK_zK _xLY@*)20)7*7$"((  +"&54>326632#"&'2654&#"26654&&#"]k"CeBd3<'5:H@ Bl&&/O/0(7Q,=o_>zd=>$<88P  ExJh,.!C~X9%K}K>D0v l!. JKPX@' f _rK _xKtL@+ frK _zK _xKtLY@! (& .!.&$ +73336632#"&'#3##7%2>54#"JHH #X8AP$Da<6BW(B/U!E:#2Agd,A\[Ji<7%9FA``3Vl8l1Tl<0<h!*9@ 7JKPX@- ~g_rK _xKtL@1 ~grK_zK _xKtLY@,+31+9,9*)2&$& +4&546632336632#"&'#&&#"%2>54#"9"J<VH #X8AP$Da<1H  W> $(J(B/U%L<BB+K/d,A\[Ji<"A%3+3Vl8lAT(V^ 1g&!Tl3U.L4 XB-Y,C61&K-!,<d/>\[Mf:QSl@f0&" / JKPX@' e _zK _xKtL@+ erK _zK _xKtLY@"!*(!/"/ &( +737>1##"&54>323733##7'2>54&#" #V8AQ$Eb=5A!BIHW_!D9#.4(B0@C5),A\[Ii=8%S@aa2Ul:,@3Vl8l0",;|@,JKPX@$g_zK_xKtL@(grK_zK_xKtLY@.-64-;.;&( +'%661##"&54>323737>544#7'2>54&#"u #V8AQ$Eb=5A!BV]$'#%8B4.?W+v!D9#.4(B0#%,A\[Ii=8%SlR +$!)8/08(qc2Ul:,@3Vl8l9/@,Je]rKpL!$! +!'#732654&##'32MhRD?1.NHRY=EXE:1*HHD;Wu""B@?  J~_zK^pL""'%' +#77>54#"'66323733##7 ,F'@4*&I7CK&M8cUTTT>)D?"?=$E>-KN2[I0@- JrKpL +7333>73#'!},X4  ^sU]}]O7/ @@'I9/?@<& JrKpK_tL,+"!// +"&'532677&65##33>7336673 !.1 hV _ (u]XG6/23(J/%?37Y99/%a&&g7{=F"2 JK)PX@+fqK _zK _xK tL@+f _zK _xK tLY@$#+)#2$2""&' +#73733#36632#"&'#2>54#"L LX  $V8BP$C`=6D1(B/U#J< 1N?[[?+J,A]ZIi=7%:/3Vl8l7_<.-0<"2 JK)PX@+ eqK _zK `xKtL@+ e _zK `xKtLY@$#+)#2$2""&' +73336632#"&'#3##7%2>54#"Q PX& $V8BP$C`=6D W(B/U#J< 1>I+J,A]ZIi=7%:H>aa3Vl8l7_<.-0<!@JrKtL +36673Y<  &jV2 8;"'s@ JKPX@"_wK_rK_tL@ g_wK_tLY@%#  +"&'53267#7376632##32654&#")$ &0 knn TRDDfe3nX103/ J28G/JbH;GXNY3(!187 (9@6Jg_zK_tL(('$%& +52>54&#"3267#"&&54>32[;wd=<2*A-Z$-(.K."Bb@[r$>_H.nNH*GW-n C*WD5lY6pw3x|rZ50c!0@  JKPX@-  ~qK _zK ^ pLKPX@9  ~qK _zK ^pK ` xLK)PX@5  ~qK _zK^pK  _ xL@5  ~ _zK^pK  _ xLYYY@!#"+)"0#0 !! +"&54>323667733733##7#7#'2>54&#"AP$Ea=6A %W\A\m\B]K $V!D:#/5(A0 \[Ii<7%">$PHc-@I1Tl<0<3Vl8lcb ZK)PX@ ~qK^pL@^pLY@  +333733##7X2\A[l\B\PHc":  JKPX@*  ~  _rK^ pL@.  ~rK  _zK^ pLY@::64/.*(&% +333>323>323733##7#6654&#"#654&#"rH 1@)7<7D)>D6%[B\m\A\cH!#!H?3XG # J@1c2"@77#D@*HP!$0fPP-!%/jXc%&yJKPX@'~_rK^ pL@+~rK_zK^ pLY@&&%1$ +3>323733##7##6654#"sN 4C,@J7\A\m\A\^HD"MC2c3"G@0HT@/hXKPX@  JK(PX@  J@  JYYKPX@ ~oK_rKpLKPX@ ~_rKpLK(PX@$~zK_rKpL@$~rK_zKpLYYY@ +3336773&&##7rG KfM?M(2b@a=[6dgS i\c!L@I J  ~  e ]rK^ pL!! +3323733##7#'#32654&##rNX)D*CM\B\m\B\aXn-4OH:IkacYc>" 283.( 4A '#(&oz#F]:=AS- ! C #5*/,1@.# J_wK]pL+)-! +3732654&''7&&54632#76654&#"KR!2"0`NLG 5!),7iJ" +)"'(-HH>*:>"O6P\J=+C;'T8<`81#9 'A&*8/'0@- Hg_xL#!'' +"&54>3&&'7'2>54&#"^fCkM1CD$!J%Gf9.C+21DU'p`9jU2.`2$6&!L P->sZ5I.IS%8C=f?"yKPX@ J H@  JYKPX@_rK^pKtL@ rK_zK^pKtLY@$% +33>32&#"3#H .:& 2N4 %2c2 OBf5E:%<@9Jgg]pL %%* +377'&&54>32!26654&#" i1/AfFdoCzRX qBP%C:@L#@@N%a>4eR1j[UEBBj>b5?A>c8=?@rKtL +3X '",e@ JKPX@_rK_xKtL@ rK_zK_xKtLY@,,*%*% +33>323267#"&54776654&#"H 3C+>I'*  '50*"%"NDcc2"D@/ /B4-!$0jW)"cKPX@ J H@  JYKPX@_rKtL@rK_zKtLY@ $% +33>32&#"H .:& 2N4 ec2 OBf5/5@2J]rK_xL  +"&7467#7!#"3267ecYM}k5Bc@ >6"A D p[^$HH/N`2@BK&p$1@!"JK)PX@!g h cqL@)g hW_ OY@&%-+%1&1 $$ +"&54677#"&5463233#3267376654#"1A+98;4 :XUaa,  ,a&e2<':)/? uD!C  (<%hJKPX@ ~_rKpL@$~rK_zKpLY@%$ +3>323#7#6654#"sN 4C,@J709R)32&&#"3#3267#"&5475JjC#E7 =[>8#?E)YnACj= I ZFA=CJddN",6?@;1, JKPX@"_zK_xK_tL@&rK_zK_xK_tLY@87.-7?8?-6.6*%'% +'77>323737#"&'532677>1##"&545"%654&2667 0 DlG6A!C$KKH{`1SY+>O  #V8AQ)C1  -%J:? QQ8%S?q`Q327#"756654,F F:N 4C,@JA @@^:1C??c3"G@ ? 0$OB/@"kKPX@JH@JYKPX@_rKpL@rK_zKpLY@ $% +377733>32&#"7,R S8H .:& +E3 0? c2 O1P--?."+=@:&$# J_zK_xL++ +"&'532654&'77&&54632&&#"71IP*;>%/ xcS1S@,,2 / }q Q.&&*?4"DTF ) %+?3%QT6|1! O 3+2'0@-JHg_xL!'' +"&54>7326654&#"76632al,aoSuL*5@2E$+* 4I'?q skI-7+lsq`!@J=g>6>J3V5VN",@) JrK_tL +"&546733>73'326670.vgIX# ^%=85 !1%FY2+Df!LE@D&@A_FHI0'&"&D 0'"&HP&O r%&Q '&L 7'&&XPD@'(98JKPX@'_qK ]rK _ tL@%g ]rK _ tLY@!A@=;75210/,*%# DD +"&'53267#?>32&&#"37>32&&#"3##"'53267#0 - n]d 0F14"'. /E24!(- tspKI& , npLJ1A %!0EM C ,>34DM C ,>3CS^ J3? S^DOS@'( 98JKPX@9_qK _wK ]rKpK _ tLK-PX@7 g _wK ]rKpK _ tL@5 g  g ]rKpK _ tLYY@1PPFEPSPSRQLJEOFOA@=;75210/,*%# DD +"&'53267#?>32&&#"37>32&&#"3##"'53267#"&5463230 - n]d 0F14"'. /E24!(- tspKI& , npL;-$sXsJ1A %!0EM C ,>34DM C ,>3CS^ J3? S^a&-#DHK-PX@'(98J@' (98JYKPX@._ qK ]rKpK _ tLK-PX@, g ]rKpK _ tL@3  ~g ]rKpK _ tLYY@)EEEHEHGFA@=;75210/,*%# DD +"&'53267#?>32&&#"37>32&&#"3##"'53267#%30 - n]d 0F14"'. /E24!(- tspKI& , npLXJ1A %!0EM C ,>34DM C ,>3CS^ J3? S^L&IL>S&IO>8@/!"JKPX@+_qK]rK_xK_ tL@)g]rK_xK_ tLY@31,+&$88 +"&'53267>323#3267#"&547#?&&#"@ - ;M*4K3>! 26J =S] 7+5LJ8:GM0{C ! C 4A '#('b)AvS^SKPX@; CD-.J@; CD-.JYKPX@% _qK _zK_ xLKPX@0 _qK _zK ]rK_ xL@.  g _zK ]rK_ xLYY@HF?=8720+)#"! SS +"&'532654&'&&54632&&566323#3267#"&547#?&&#"&&#"1IP*;>&49:cS$dYIX>" 26J =S\ 0 0B@,,2#5"6q Q.&' D3DT H_A){C ! C 4A '#('e47,!F ) '(5%QT;,@) JfIKJL  +#3#'#73'&&7#97dGWV}  ;ţyD #A! & D& H3+& F& A & C& K3+';& L0& I 3+& D||3+& J;?@<ee ]IK] JL +#!#3#3!7#737#0r#'#i6 ;LKL & Ds;"9@6Je]IK]JL" ! +332#32654&##32654&##yT[F;(4:fA#T3G-4I[[?F/8P;AA;H  9/32&&#"3267do&MvQW@"8$8T7G?#@"#Dwf@lA$G2Sf4FN L -  & D*-!!& G3+-C&z-!& F3+-& B; '@$]IK]JL ! +332#'326654&##ykyOm19Ml8OB>;qseXKFyMPJ ; 7@4e]IK]JL ! +37#73732#'326654&##3#5BA3kyOm19Ml8OB>$tsQqseXKFyMPJQ "& G 3+ ;; /@,e]IK]JL  +3!#3#3y2"(;LKL & D& H3+!& G3+& F& A& Bl  3+ & C& K3+';& L; )@&e]IKJL  +3!#3#y1'2;LL-C >@;  Je_MK_NL    +"&54>32&&#"32677#73 hw-SvI4S$!D)Cf9EH/"o>%VrjLe9JNOASJ -& H"3+-!& F3+-#C& %-& B); '@$fIKJL  +33373##yX22WxX77;^;;@8  f  eIK JL +3#73733733###37#YIIXWFGXX77GCSSSSC[PU)!& F3+:; "@ JIKJL  +#77'73 G]? H]@ 122N1t & Dx& H3+i!& Fn3+l& A:& B  3+: & Cpb;&i& K3+':;& LD& Ji3+vb;(@%JcIL  +"'732673H) %5 vYx[ K,5,XKvbX!& F]3+;%@" JIKJL +3366773#yX: iak?/; ! +#;& V;@IK^JL +333yXj;Mj & D;&%C C3+#V;& w;&y Ӱ3+V; *@' JIK^JL  +37'7373+7g32'26654&#" kq(LoGep%ImD@; ('J H_MK_NL"!!)")&*( +'7&54>327#"'7&#"26654'N.8+(LoGQ5/,5)%ImHS6  5=Z132!#3#3!'267&&#" kq(OtM"5-"((&X-I`/IxgHg;LKLLOMGN; +@(g]IKJL $! +332##32654##ycT|1.=.GTe7;VDah"=?S; /@,hgIKJL $! +3332##732654##yX0cT|2%6GMe8;rXDaff:?V-x,D"8@5J_MK_NL""&# +'"#"&54>32'26654&#"hUjp(LoGep-W@l>X.D;=Z1ExgHg;zhNfONFMNOFM; 3@0Je]IKJL ! +332#'#32654&##yCHdaST1@8HF237;AX.>5+& & D!& G3+#;& C%7@4J_MK_NL%% +"'532654&'&&546632&&#"S8G,2H+1.:4X7.I @!/8'*5>uT-0,B84K(H /'!' A9UZ & D!& G3+C&zv!& F3+#C&  C&KPX@ J@ JYKPX@~_MK_NL@#~_MKJK_NLY@ && +"&'532654&##57&&#"#6632F>6<,5<4 -/?@LXOne=U,4M.U X9///R]$CLsig,I+]K@4U2;;!@]IKJL +3#7!#miiLL3;/@,e]IKJL +37#737#7!#3#m3mm''rr3GLLG;!& G3+%;&zz.#;& 3);$@!IK`NL  +"&547332673[[ JXK23BBOWOpVK)\%).DDn`m3) & D 3)& H 3+3)!& F3+3)& A3) & C3_!& E3+3)& K3+3');& L3)R& I  3+3)& J3+< ; !@JIKJL  +3336673z>W" `;!G@"_F;!(@%JIKJL!! +333667336673#&&7#aU  U \^;!GM"I"PK#KQ>7&F & DpF!& FJ3+F& A^F & CL; &@# JIKJL  +#373#'6gZKbp_P/ =;"@JIKJL +3733o/aYAd-c= &  D=!&  F3+=&  A= &  C; %@"]IK]JL  +#7#7!! [b @LASM &  D!&  G3+&  B\  3+QGL?)&f 3+J @W_O   +"&54632#&48&.'".F%%5!' XKPX@noU^N@U^NY@  +73!73#'!'74'474'TTTT0 )@&e]oKpL  +3#737!7!@6d/OO6W& 0@-g]oKpL   &! +!#"&&5466333#"5;EO\);gK<+*@'&JoKpL++ +#33667336673#&&7##467#9Be "^   _e   ` "Q+V$$^/5OK6A;0\#$W+SA@>Jf#K$K_'L +"'53273!3#!2% =Y@:@XXFUJ Jb.6MkM[ED&O@L Je  Q ]#K ] $L"! +3>7!!33##!3#7!!#T83-]UC#@ @YJQlfJYF5[9U'K(}vx=KQ >I.[bM )8Av&-L@I) J  g R]#K ^$L+*('$#  +3667&&5473667!3#7!667#37]9W7$77!3#7## -)%&%cP9W)S "!4L NA<.x<z1uyo+?\1'=$K"PX@c]#K]$LK(PX@#Wc]#K]$L@$gc]#K]$LYY@ !%"%!#+7663232654&&##7!7!36#"&#"  C;7%2)., DaN&QB.@5-H&F4PGJ9(D) '=,K"PX@( e  c]#K ]$LK(PX@- e W   c]#K ]$L@. e g  c]#K ]$LYY@*('% %!# +7663232654&&##7#737!7!3#36#"&#"  C;7%2)., sˆaN&QB.@5-H&F GPGGJ9(D)  [}-@*J#K`+L +"&5467'733267H9cL Vg="0 H7 22 ;F ! 9@6Jfg#K $L % +376677#73733##7654&#"!'ZS^ Z%WOZg&v_LaaLejY),EHa_,$G@D JI~]#K_+L$$ +"&&5466733'2654&'#7nbO:h^{iebGpoJTZRb+~ 4aB9`A oFAl@OXG1H *D+AFG>R@O. - <J~_*K` +L:81/+)"  >> +"&54>32&&#"32677332>54&#"'632#"&'nc4LbC)8 +[) 4(-J:(5..$BOY\7Qj@=IO nD~c9,F5Xkn/O[' $7]pu3IJH+wkEg<)*M=%;@8  Je_*K]$L%# &%%+3654&#"'663232#'3254&##sq%(3L@AT^'HSGTB;Q"G I?-V0P1Qh2L;0Zs<@9e]#K] $L ! +3#7!32#!3%3254&##@@S_'HSUY SB;P|N0P1Qh26L;0* =@:f  e#K ] $L &! +333733#32###%3254&##*YY@T^'HSssSC:P```J0P1Qh2 L;0I*KPX@!e_*K _+LKPX@%e_*K$K _+L@)e#K_*K$K _+LYY@$"**  +"&54>3233##'26654&&#"Bv1[}L\p3?YYG 3TuGLo< H<:[> V ]~GL}L  /6LAzb:Oan8Z6@mFag*4@1Jf#K $L +33!3###!3'&&'*Y@']}W4aFע  13MMmD** 7@4 Jf#K]$L  +#33'&&'!'9^X֮+h[O6Ny)\$&V.Ȱ"D@AJ e  e]#K $L! +#7>7'7!#'##7#7!!&&##"(h5I>{7; Z #Y#N6^R*3e7;@O'DD1Q4ޥl962* ?@<J f#K] $L  +33!3!!3'&&'!'*Y@']}uFע  l(13MmD**~HzK(PX@  J@  JYK(PX@]#K_$L@!]#K$K_$LY@%'+##"&'732673#&&7#Յ .?8D.$   "2&^gX* p,`/:R-J>F6@2S(D )@&#K^$L +33!3!L9LZ,Z)( {z6EV5@2 Q]#K]$L +3>7!#3#7!!7#T83-]UC u[9U'K(}gx=KQ >IO E8uKPX@ J@ JIYKPX@]#K_+L@]#K$K_+LY@+"&'532667>7!!## -)%&%qZ "!4L NA<.x32'2>5&&#"7"&546323"&54632[3`W~/\V>bD%_R>dG%a%"# \I]}HO77333#7!!#T83+ZRB1U,φ[9U'K(}vx=KQ sO>T-!?$.J,6(9$D{Y5W3,@4AW8I@710 @""WH4Q5[bL=)U:b&'jGB$! %'$! %'\6#<&2:a@^ J gg   U ]#K  ] $K_'L65432210"!$$*"+3>7!36632#"&'532654&##73254#"!!#T83-]UC#56 07(%8OC737"'7 %K)%(}vx=KQ >I +&+ 43; @"81!  )8ZZ"H@EJe]#K$K_'L "" +"&'732677654####7!#32V' '+< 5 eLY*ZU5`N 3>'"Q{OONL*WaZM5@2J]#K_+L +"&547#7!#3267>9L \]$* DD *OOJ J($ȵJKPX@$e#K^$K]'LKPX@!ea#K^$LKPX@$e#K^$K]'L@!ea#K^$LYYY@ $# +"&5463!!"3326654&#!3!3#l4072 $:#-*Z,Z5im+#%15 '$!%zm JOV>M5@2Jc]#K$L +"&5467#7!##"3267s/4V;}ć,85.  5)=IQOO8"+<Y 3@0Jg]#K$L&#+!#"&54677#7!#32673>&nAKQ$$(07l,HZ#GB$NN! %'\6)9%9@6Jg_*K$L%%&%%#+36632&&#"6632#76654&#")ldW! "63"d;KQ5Y4(02a(HnhO@DYGB$! %'*((Ե#JKPX@&e #K^$K] 'LKPX@#e a #K^$LKPX@&e #K^$K] 'L@#e a #K^$LYYY@"!  (' +"&5463!!"3!26654&#!33333#4072l }#;#-*iZZY8hn+#%15 '$!%zzq!MOVH&22H#)>@; Jf*K_+L'&%$"! +"&54>32374&'3667#%#>Q1^Ty-Y3Rr>72S<656:[> \I]}H 8Nd LbEp;A@>Jf%K$K_'L +"'53273373#7#@% =W.0XqY2DI Jb]KXFK"O@L Je  Q ]%K ] $L +3667!3733##7#3#7!3#R7$Il#0/W7ni8X4&D7R((gS{ YY sF#+L@I& J  g R]%K ^$L)(%$"! +367&&54677366733#7!677#37R7H)""1&K$,2cB7P((EL!g$(R,#3? 7.   4@M08v8F#n@ JK"PX@Q_%K_+L@!Q_%K$K_+LY@##+"&'532667>323#7#&&#"  .)*5N:"@aH6Q(Qe *2*5IL*\KCbA :'^USr;DK+6_@\#.J gg gW_O-,! 20,6-6'% +!+  +"&54>32#"&'6632"32654&"32654&ev8XyOOE(WI5S!#V5TP(ZM<]"R D9&SHCrDD0(C( A=M>)Q6B3-&#)%DI;&$- 8@5eU]M  +3#!#3667#3YNKU;;TK+Wtvv,#0 1@.gW_O  +"&&54>32'2>54&#"CQ&"BcA_X!Ab?*?*)7(?++ 8b@?}g=un=zd32&&#"3267+|#K{XCs "a:Ud,bU>` ^v;lU2J!W[P e$@!U]M+3!7!{j|N6W *@'U]M +3!####rtYdcXcf33d> 4@1eeU]M !+3#7!32#'32654&##}_cg\jt|<>4CiJDOAJbG/+&+E>@;eeU] M! +3#73733#32#'32654&##Wcut0X0cg\jt|<>4CiIIOAJbG/+&+/#>@; JW_O## +"&&5466733'26654&#" L`/7eDuYii5@)Kd;:T-D69V2D <`7DsNd@9gR/K=b7D,4-XS B?5B.2'FD7HN$%$P3!8@5J~f%K$L!!& +37677#73733##76654&#")XHKX@>JMhMASSAP UF!Jd  2/CHd'!,6@3'J`+L#"",#, !!+"&5467&&54673>73'2654'UYM[0-X!'4K6[<\E+&c_/8@G5/ KI>p=7_3(#$ )M-,YuTXu30]&UmJ65EF5K&&*1!9R@O) ( 7J~_,K` +L53-+&$ 99 +"&54>32&#326773326654&#"'6632#"&'ZV&D_9D&-%'=*-1#* "X# -6O*&#!:!GICgH+@A oeC{a8C1O\-?I OL2C E iSCj?5##2G@DJg_,K_+L%$+)$2%2 ##+"&546776654&#"'66326632'2654&#"FP^"&+GE 7SR-]B=8331* KO4  EA?),!%+/-  JK PX@)n  g]%K  _ +LKPX@(  g]%K  _ +L@,  g]%K $K  _+LYY@ &$- -%# +333733#6632#"&54677#%2654&#"XY#6QR-]GP^1dw>7321*jjjEID2T2KO4->?),!%+/0&KPX@!e_,K _+LK"PX@%e%K_,K _+L@)e%K_,K$K _+LYY@!&&  +"&54>32373#7#'26654&&#"]k"CeB^jv/XrW2oCiC/O/0(7Q,=o_>zd=o` AqFIC~X9%K}K>D^JK(PX@f%K $L@Ue%K $LY@ +33373#'##7#3'&&'#rW3dfU#}^.x   &EE? 7@4 Jf%K]$L+#33'&&'#!'9Idf   'VR.QFEE"F@C J~e]%K $L! +#7>7'7!#'##7#7#!&&##"6_,B6l  -0UQz@ R%',Q-5#:&33(<(xxxx<*%$ hJK(PX@f%K] $L@"Ue%K] $LY@  +33373!7#3'&&'#!'#rW3df.x   &/EE?ܗKPX@  JI@ J IYKPX@]%K_+K'L@ ]%K$K_+K'LY@%(+##"&'732673#'&&5# 7)A2  '`]W |T7%gLCH2 (?F( )@&R%K^$L +3333!R7DbXbbXqt(2F5@2 Q]%K]$L +3667!#3#7!3#N7+Yx SN7U((iTw@R_|EwD"JK"PX@_%K_+LK-PX@_%K$K_+L@'_%K]%K$K_+LYY@""+"&'532667>32!##7&&#"  .)*5N:!"dY=' *2*5IL*\KCbA F.'^USr;-@*J]%K$L3+3333'!##667###qr8 RbPA E=>WF.3%M ;R%0)>@;g_,K_+L %#) )  +"&54>32'26654&&#"7"54632]k"CeB^j"Cd>/O/0(7Q,=J0"%"o_>zd=o`=zd=IC~X9%K}K>D0./3%*6I@F  g_,K _+L,+ 20+6,6&$* *  +"&'4>32'2667.#"7"&546323"&54632ap$FgEgt%HkC4W58.:U/B"x#yi:s_9te(FtEHN$"&"0t' ]p ]F9@6 Q]%K]$L +36677333#7!3#1N7+Xw-P+bN7U((nTv>P^z2D#)7@4J_,K_'L))+"&'532654&'.546632&&#"w;L"S)DR'+35bD3J!':#AF/(/5gQPA2D+:G/>]4AN80D&8H5=d<"5KPX@-*'J@-*' JYKPX@$ e]%K] $L@, e%K_,K  $K_ +LY@10/.,+)(&%$# 55 +"&'532654&##7326654&#"'66323733##7#+SS5?K)O_|2+&+ 43; @"81! D==$L@IJg]%K$K_'L $$ +"'53277654&#"##7!#6632e#<-&%-L"-Yc'$L1=Q-I K c'#FF!CH KX+5@2J]%K_+L +"&547#7!#3267D> ?@ ( C4'%FFF (1$ȵJKPX@$e%K^$K]'LKPX@!ea%K^$LKPX@$e%K^$K]'L@!ea%K^$LYYY@ $# +"&54633#"3326654&#!333#m4072 $:#-*rXbbYi+im+#%15 '$!%/BOV >5@2Jc]%K$L +"&5467#7!##"3267l/4G3[c85.  5)7F FF.8"+<="3@0Jg]%K$L""&'+!7667##"&54677#7!#3266773 "a>CF  '"&QG Xr#B(4FC06FF=#(&_X8 *9@6Jg_,K$L**%*%#+36632&&#"3>32#654&#">F) #4C+>IFXG !%"OC1qGE I BA 2"ED(P-!%/jX((Ե#JKPX@&e %K^$K] 'LKPX@#e a %K^$LKPX@&e %K^$K] 'L@#e a %K^$LYYY@"!  (' +"&5463!!"3!26654&#!33333#4072E  #;#-*rXccXccXi"hn+#%15 '$!%//@OV0v&RRr0#(3@0Jf,K+L(' +"&54>323734654&'7#667#]l"CeBce"Cde!1E`"#c/Jfo_>zd=pW>|g?@ S=  ,= z  _! XJ#:*%@"%H_+L**+"&5467&&54>7'26654&'[qsf 7BrPAsW236DMAtL7K&2-\_; cahA*5?!K !0!*hLP{GI8[65KsY;FZ&'L'"$3@JKPX@"_,K_+K_'L@&%K_,K_+K_'LY@&%.,%3&3! $$ +"&'532677>1##"&54>323732>54&#"1SY+>O  #V8AQ$Ea=6A!Cz{;"D9"-5(B0QDEYG!#!H?4XH #!J@1XrH 1@)7<7D D@*F!$0fP-!%/jXc2"@77#T+/ +j/ +4j/ +j/ +j/ +j/ +aj +~j<3+3+3+ 3+ 3+3+3+k' a!PaG5)&f 3+]aaG5)&f 3+*BK1PX@f5K6L@f5LY@ +333#*Y@FOK QK1PX@~]5K6L@~]5LY@ +3##!#7#̈/K@ @K/|.) h@ J IK1PX@5K6K_:L@~5K_:LY@ +"&'73267#373Ca U5Il!Slʩ," MJXZ=BpywdB-VBK1PX@f8K6L@f8LY@ +333#rW.3IU> QK1PX@~]7K6L@~]7LY@ +3##7!#7#c#L22L#bLA>JK1PX@8K6L@8LY@ +333#>7rTF YlrSC  /1 <43 @R61=@:Jgg_+L(&" 11 +"&54677>32'26654&##732654&#"!bm44aPU`4I7gF-@!@N #XN1309 3? qg*?h?YP& OKEm?H0K*7>70327#"&&'0'0>54&&5461"32>18r_9=;+?&&*B2.\NbHmh@R*"JCBHK PX@6n~||W`P@5~||W`PY@YWGE?=(& hh +"&'7326'.#0.#"1'0>3276654.54>1032667#".1>32)4#8=/7F  %./&&2&*?>*-/! =S32!  )20"*:> :E" |E^f(=7; "-" %KVZ*!E>1@5 '3F. ")& TRCz,04 !OR@O@?)(J~~|W_O#"31"O#O#+#&+'0>323266710#".#"".1'76632326654&&54>73+6 <<6)"  +/% *66$<)'#1h  %24 $30 * :6$.+@@+ !!-=+| "."3S/-]Q &*#* 3267>54.#"1'06654&'.54667>32>32326732661'0654&&#"06677"&&554&#" #!)) !49-("."  ! ,=&)I4 #1@)#& " 5Z2,! D 0%<89&"6 .*   ') ) _@9& J;: H    ~  |||||| W_ORPECB@642/('" __ +"&'46&#"'>3232>54&#"1'7>54&&#"#"&&57032632>324  ,70C)VF+ /72 )% '' $!K&/&0!10.0# 0>$$!!LG4q 2! ! &@KKEK A,:!  l  *2'A3%/3DUU!!$0@JKPX@&ee_qK_tL@$gee_tLY@+*(&! 00 +"&'5326654&##77#"&546632&&#"33k*^#&\.FT%K@N]UY4\<"2&4",2Uo?T.H(:5FWF=`7 D9*,*GVXAk?.@JK$PX@&gg_oK_tL@$ggg_tLY@)(&$  .. +"&'532654&##77#"&546632&&#"332]1Q #Q8PfGM@ +Y`+Q8!+/548 AT*QKE:?>JL4W5 = F11+7/M.qwO@QURO$\ on J  ~  |  |gg g  WW_ OxvgeMKB@9842(& +".546332667>7>7&&#"32>53#"&54>7663267#"&&54667032676654&&'#"&54632>54&'.9 1"$  +$>YK**8*4"6#=q[59'$#K@)9O04:':98[(C/'7R' %&,HR' -1 % 7  !1# 1<(![ '*!(7&  QX-SY2%-$ $5F*)(.Rm?0%PF+44+I:( !. B(/H4$9)'QE*$ ,<"%095$P8   :V23NcuA(@h>:~@{W >(=\ sJ  ~  gggg W _ O}|wuecQOEC:8/- +".5463232667'0>776670#"&54>54&#"'0>3232>7667>32032>73#"&5467667>54&#"9A1"$  1+8J=%?P1C) O?2:4 AL%0:< 1CKH -" %. %\db+"%4nW/- +0,!#/43!:+$mvcD (,$ (1-;B(|E"3k]9 @MICG$PBSS@PH/J~ggW_O75('&% BB+".5463232667.54667663>54&1707>79A1"$  /)*E=68;oA73A00 !@) !A5`|CPa=:=pX3& '6/ (7'  5];32&#">32326670#"&'67>54&#"267&&#"";%=%&T)  BR+4[u@---):cI( 27=DLT-+&/UqCG(!<!HA%6D(&E +WBB<?,%<20x,9$J(4$3 %# H+  *;>5`K+  .Nb5,8 <}qZ4*$gl\3CY&D-!11!B5We0Dq"a 5@2eU]M  +3!##'3#3#aGxCCCC6k5`` m~@{z ~{xM = J  ~  gg  g g  WW_ Ovtkiba][QOCA;:42,* +"&&54>54&'"#"&54632>54'#".546332667667>7&&#"32>53#"&54>766326732>7%!   .0"01<(![T9A1"$  -$>PA* W>4"7"=q[;@-$#K@)9O04:-A?8[(C98om !# #3> #EF=  .C-^ NcuA(@h>&5. (7&  C}XCL%-$ ,AN*)(.Rm?0%PF+44+QE1 !. O(@h+"JD() 5=,) ʰ3+2F >@;  JgW_O +"&&546632&#"3267'~pIOo0]0PU+K>W)X*/VS) Zpl] 8" ; zSO|a ?@< eeU] M  +3333##'3#3#axCCCC:6[5``a &@# Jt +333#%5aL5M:"65bca\ ?@<JeeU]M %!+3!2##'3#3#6654'axBl=cxCCx$/Sm[>_65`1@32#"&5467232654&&#"#"&'32>54&#"&&5466320654&'&"=Y0EqC :b@0<" 0%"$#-"1!./K+5#9#A3&% (M?&$<$%?(%# (EX{% '4\;=hE ;-)O3.29))< ,73,36aC   6NZ//36H(%'6Z4$(B(#--O:!  h8@10d vV |YL JhI  ~  ~g g  g g  W _  O:9rpRPJICA9:(& 88+".54>3232670#".#"32>54&'7".5463326677'0>7>77667>320>7"!':\S3@.."%#  /&DCF(6mY6 2,#3Jk.;!1"$  -',F= 8R,E07QB %&  G N `5%$ !RSF+ %!.Oe6&% #7A< ')+#(7&  6^;A1 ":e_/ $Ze5$ 8"'!** UL@@=lHG+ JvHW`PigOMDB+"&5463232>7>70>7667>1326670#"&54>7>10#"&&70>7>7>H3(!%+ )%7_VW/?|i# %"9?>,="5U2062(* 8> (/0"(&,' 282 0Si9=Y#3D?1/$!SYP(QWg J:*;#  "=e~@Vj -HTM8 8NUPUfd'JpOQ DV0NVI[ HTDN  i|H 1R2ET,  G8C[.B,d6c1JBf6k4GUDD0;KHT4<!v/?@<Jg_wK_xL+)(&!// +"&&546677&&546632'2>54&#"33#" Ue.7_=0;>kBy+Yb@fF%YM%@'DN  i|G 1R2ET,  G8D[.ZJJ=jMbj=.0;KHT4<I,i@ (JKPX@goK`xL@goKpK`xLY@'&%$ ,, +"&&546677&&5477333#"326673#7#G\-7_=G; Y!NI%i|BAJd; ZYG:R 1R2CR+  M479KIX1:Bf66c1 #+K@H% JegWe_O   +"&54>323#773#2>54&&#"@Q"Bc@4D B'RCB/Qbo2 ;&KUyL.; ""(/5@2*(JgW_O  +"&54>3232676677&"#"6654'nq*SxNH`'.-^-,YI4% +{$)/L9A m]@}g><>Bd ?4 -'lo)H'< V M@Jg geU] M     +"&54632'2654#"3'3#"-2/L; qrnC\CP&%*7>323266730'>54#"&1 ,+CX3%! :fO NR#2@H#;L+0+" ),$5 # .3%! ::29++L/%77%<@4 /FF/(?S@P ,J~|gW_O*);931)?*?! ((+".5467'0>7>32>73'267&&546326654&#"%0 ,*>K(+.4!/0*@*<)"  +M7( ),$5 # .3%,TZ%.&'1' 1o+%^jM[{Q4GVg@d"% MJ~~g g W _OIH65HVIV?=5G6G*)$# 44 +"&&54>17#"&&5467'667663273>73026676654#"26677 !*2OXO2" 6$$&  A #;#^:)'.v'B. 3T6N2GXx!B: "01-#"51O/BF=&{",B>7*G )87@ &D"(;!(@:5 ?I1GH17T,"J (+EPN; -N2(3<@ 0:"*J@G  )#"Jc_zK_xL'%  ** +"&54>32&&#"32671#"&'73277Yn'Ih@#E7 9V0>8&B F:  ,  ddHb9 I ML=CADI4?: -z@JK)PX@&~cqK_zKpL@&~c_zKpLY@--%%#( +333>323#"&'73277#654&#"X+4C+>I7) D7  * 4G !%"OC1A 2"ED(ADI4FP-!%/jXr(9@ %JKPX@#cqK_zK_xLK)PX@'cqK_zKpK_xL@'c_zKpK_xLYY@53-+#! (( +"&&5466773632#"&'##326732>54&#"+M0Pb2X.%'mf"A\:6C!B\aw7.'015%>+?I(&),_Mwx{a@x_87%R,DIF90<,K]1AR2,@JKPX@+  e_qK]rK_ tL@)g  e]rK_ tLY@)('&%$#" ,, +"&'53267#737#?>32&&#"3#3#0 $( E]\]d 0F14"'. s sqpGLJ;7F@%!0EM C ,>3C@S^!!4@JKPX@!g_zK _xLKPX@%g_zKpK _xL@)grK_zKpK _xLYY@/-,*&$44  +"&54675&&546632373#7#'2676654&&#"33#"PNV=,0R4CI CrF [,>] 5.+C.1 )D), N32366733#327#"5#"36654&2667#@Q) (Ea:9@H  I J$Z"RF7S3"B6, \[&$>Ek=6&1JX+>b $@c):\G /LKPX@ )& J@ )& JYKPX@&  h _zK _ xL@.  hrK _zKpK _ xLY@'@?.-FD?L@L86->.>('$" ,, +"&54>323736632&&#"32#"&'#7#'26676654&#"%2654&##:G'E]60:!8 P/'JD+@f|xTT;L; (R$E8+&%@1$-Od!7 ^XLh;8%SC%(L^IQMCX(#Cc132##!!3267#"&57326654&#" *)E_32##3267#"&547&&#"3277326654&#"j2;KG-Ff@LMAn;>&D(&I3]e% +#%0YB?0>JAmBB;5U3 =GKm]"!=1)!YI'"-<H@@ +)JKPX@+g_zK _pK _ tLK-PX@/grK_zK _pK _ tL@- ggrK_zK _ tLYY@!>=/.DB=H>H75.32373&'2>54&#"267&&#"CY,I,=O  #V8AQ"Cb@6A!Cr  =S"D9"-5(B0+:D)/,,04$1#05(,A[SAi?8%S1R" D.Oe765/Qd4l0@ JK)PX@,~~ghqKpL@)~ghpLY@00$)"$)# +3&&#"#"&54632332654&'&54632#"'Z]  &M=8X>   F?X0  2)QF . 0)LLe6@)*  JK)PX@2 h g  gqK_rK p L@2 h g  g_rK p LY@66420/-+(&""$"# +3#&#"#66327'&#"#663237332673#"'32673#"'H:  4:+  4:+2X;  5:+  5:+1>Bn>B>Bn>B8!H@  JK)PX@qKzKpL@zKpLY@  +37&&546677374&'66`2(2*G+.X2'0)E*/K+'5+'3N0,H-L/+H.~1=)/=N"?I@   JKPX@$  g_rK  ] pL@,  grK_zK pK  _xLY@A@ED@IAI??%&/&% +333>323>32&&'#"&546776654&#"#654&#"%2677"rH 1@)7<7D)>D   E;+=aN!#!H?3XG # J@1 -.c2"@77#D@*t 6 YJ(7=Cy!$0fPP-!%/jX4&.,%"+5@JKPX@!g_rK _xL@)grK_zKpK _xLY@-,10,5-5++&/% +333>32&&'#"&546776654&#"72677"rH 3C+>I  F;+=bO"%"ND1 -.c2"D@/t 6 YJ(7=Cy!$/jX4&.,  "-8y@ 4+-JKPX@#g_rKpK_tL@'grK_zKpK_tLY@ #-%'$$ +&'#"&546326654&#"#33>32'3267&#" <%0@F8*#N"%"ND1XrH 3C+>IN ) #' $813Eq!$/jXc2"D@/"3Ga',)G@J'&% HKPX@ pL@ tY@)) +.'566554&'%726654&'&&'1K,   &2N)!&  -,+ %)m, #B(+OR._ :%.J$,"+6K@"J43+%$# HKPX@ pL@ tY@ -,,6-6 +'7&'566554&'%7#&&'7&&'&&'26654&'V%%   <%H&2N)/#6_ / t)*.9%)m \n#B(+OR. $ :%,/#,;@8'&  #JH_zK_xL&*%- +'7&'7&&#"766327#"'4'3266H*3Y &)@6P31*5"CdCM323/O/%<+;0 &W )9%?2I=zd=';C~0K"$2@Y@V " J  g_zK  _ xL43&%:83@4@-+%2&2  $$ +"&54>326632&&#"32#"&''26654&#"2654&##Yj"DgDIP&h@'KD,@frTSBW`<:P)687Q,;$)Oe!7o_>zd==.86L^ISKCY72/9IJP8DK{HBE- -03?I+1:CNZ@W&$=9'>81J%Hg _zK _xL32MKFDA?2:3:*$%%%& +'7&'#"&5466336654&#"5663266327#"&'"&4'3266#"326+- $d;AR?n<=%D((M,?Y`AO3-+4"DgD#7:P) :&7Q, 8^#84:=@5U3 =GM64/9,7#@1E>zd= JP$4$K{1+!U2"(1:EK(PX@ &  J@ &  JYK(PX@%   g _ zK _xL@*  U  g _ zK _xLY@#*)DB=;9864-,)1*1$" (( +2#"&'#"&5466336654&#"5663266"!654&3267!'#"326oYj"DgDIP$d;AR?n<=%D((M,?Y`8^ o_>zd==.4:=@5U3 =GM64/9I\JBE8DcJ1+!U06",;H@E  *J_zK _xL.-64-;.;)'! ,, +"&54>32&&#"3267&54>32#"'%26654&&#"Yn'Ih@"  9V0>89"CeB^j"CdC]6!P /O/0(7Q,= ddHb9IML=C)4>zd=o`=zd=8 KC~X9%K}K>D06<5>HZ@W%$" GF98 31.J#H0/G_zK _xL@??H@H<:-+! 55 +"&54>32&&#"3267&54>327#"''7&'7&#"26654&'Yn'Ih@"  9V0>89"CeB8+ /"8"CdC3)/ !P!7Q,t/O/ ddHb9IML=C)4>zd=267c=zd=23 2 WK}C~X# '@$J]rKpL& +376773#76654&#")+X,HKX@>JLz UF!\v  2/BIv'0I@F%&Je]rKpK_tL0.*(#! '' +"&54776654###32326732654&##66`l-XrNXM7!,  t?M01x>6YHAFN 4/-y 1E 28!&g" #@ JHrKpL  +333667rH E4.G/ 4c'BQCa2Q#KPX@ JHK-PX@ J@ JYYKPX@_rKpLK-PX@rK_zKpL@"rK_zK_zKpLYY@#%%$ +33366326632&&#"&#"rI #N( C   %3""H;3d86/!S /cL"#-KPX@ !JH@ !JYKPX@ g_rK_xL@$grK_zK_xLY@%$)($-%- ## +"&546733>32&#"&&''2677"D+=aODH .:& %?1"   E: -. (7=CAc2 O'@O'# 6 YJ>&.,#-7KPX@ '%+(JHK-PX@ '%+(J@ '%+(JYYKPX@"g_rK _ xLK-PX@&grK_zK _ xL@0grK_zK_zK _ xLYY@/.32.7/7! -- +"&54673366326632&&#"&#"&&''2677"D+=aODI #N( C   %3""G;(  E; -. (7=CBd86/!S /bM6 YJ>&.,,k#G@ J HK PX@_rKpL@gpLY@ $# +3#"&'73267b'J#IKP-t F ,#,s@ JHK PX@g_rK_xL@gg_xLY@%#,,  +"&54677#"&'732676632'2654&#"]FQ/'J#IKP-4.AA&O7,)##& KO4 F KC1S3H@(+"&)1~X@JKPX@_qK_xL@g_xLY@  +"&'53276632&&#" ?XHL" "* WM JrPaI:8eS^7_JKPX@rK_xK`xL@rK]pK`xLY@  +"&546733266773#7#=IFYH &"QEWEH 3D DA(G+ %.i[c2"3( JKPX@%p  frK _ xLK PX@)p  frKpK _ xL@*~  frKpK _ xLYY@&%"   +"&54677#737367733##7#'32667'=IDD5Y5WBB/H 3DX &B= DA( B (Bc2" %E:+8O <80JKPX@$~ ]rK`  xLK"PX@(~ ]rKpK` xL@,~rK _zKpK` xLYY@ 64/.-,(&  < <  +"&54632"&5467332667733266773#7##"&'#.$>DEYH!# I? X#!IA1XrH 1@)7<6E'-#FD@*F!$0fP0 !%/jXc2"@77#3" k 3+1",zKPX@ (J@ (JYKPX@_zK_xL@ rK_zKpK_xLY@'&%$  ,, +"&546776654&#"566323266773#7#=I$ )0@% !%"OD1WrH 3C DA(  C 1=+ %0jXc2"   !-K@H  Jg_rK _tL#")'"-#-!!$#& +'&&#"'66323632#"&''%2654&#"q* &90]#:/?L>2AQFP:,!- 0KPX@+ #"J@+ "#JYK PX@ p_rK`tLKPX@!~_rK`tL@,~_rK`tK_tLYY@0/%$&" +7332677'&&#"'663233267#"&&''#(5  &90]!  !*/l01#O(+&AC: ''B$>'2<"v@ JIKPX@hrK_xL@ hrKpK_xLY@""  +"&''#3736632'2654&#".<2ftYSf,7 ,;F2 -8tb:/=K?()" *@' JrKpKtL  +373#'sYSf{Y[@""I@FJIhrK_xKtL""$$ +3736632#"&''2654&#"sYSf,7 ,;F8.<2b:/=K.7t@&()d@  JK PX@prKpK`tL@~rKpK`tLY@ +733267373#'#(4 $tYSf{Y["42!O%/c/<+C@@J~rK`xK_tL('#!++ +"&'532677>1##"&5467332667731SY+>O  3D+=IFYH &"QEWL{QBy4 ,0+95 )2,:9d3+.<  #0 MK$PX@_,K_+L@g_+LY@  +"&&54>32'2>54&#"CU*&HgA_^%Fe?*C//7(C13 8b@?}g=un=zd54&#"'6632!GN-$#L),8e;IQq_&G5C5 &% ?,&N:Kw>WNS1+u@$JK PX@gc_,L@!ggW_OY@ +++"&'532654&##7326654&#"'6632:X'#a4JSI>;A.N06'.H%))`CS\]W:C4nUMA=AI#C0.1 >(WGLj NA9d?X& yJK PX@%K^$LK$PX@f%L@U^NYY@ +7!733#37667#&eaoo&/  P7N+P $" D A@>Jgc]%L   +"'5326654&#"'!#6632aB$S,FV'H>4 %aI<*XjAo'U0O.=B SPeX-[L.* 0G@D  Jg_*K_+L '%0 0 +"&546676632&&#"36632'26654&#"Th D5+vM6&(_#U4IY=^71D$45$<) 0 kpE4,0 L&-^V2cQ1J8Z38= .($?(,N @]%L+!7!,u |NF| (65@20J_*K_+L*))6*6$" +"&&5467&&5466326654&#"26654&'EY+dY&/8a;AQ$/L,4=3lDG6.5A,2@34.H*B 1Q1Mh"F7;T--H)5I3 RA5]9C5+2=5-:%; 0G(?/4;T2.s@ JKPX@gc_,L@"ggW_OY@! )' .!. +"&'53267##"&546632267654&#"w?:#dwO0SY32"&2>7X[+FcA\X-Fb2.H5&-E1 ~u;j@woHe:HuC&dBnCX0 _& 40 S1 X& D " 6N   T2  >:` `3+@ {a a3+6t` `3+?u` `3+>'` `3+ F(` `3+D;` `3+\)_ _3+;*a a3+9<` `3+J{: 3+uA{ 3++rt 3+7ru 3+1p' 3+E~( 3+S; 3+[ ) 3+;w* 3+I{< 3+S& CJ6& 'u S& 'C +=& ' 7 & 'a 1& 'u S& 'C E& 'u S!& 'C S& 'C S& 'C'  v"7: ް3+"}){ ް3+~3t ް3+w4u ް3+~-' ް3+w+( ް3+w*1; ް3+:+) ް3+w$3* ް3+w1< ް3+~"' R'  RR3+R3+6&' %@"a]rL  +%"&5463!'3# glqkcc&tvCmX&I $@!a]rL ! +7!2#'3#Xkqlgcc&vtCmbr ,@)ea]oL  +3#3#3 nFnnFnhHDHb2 ,@)ea]oL  +73#73#73HnFnnEnHJFHHQ!@JtL +3#'X([8BAc"@JtL +3#']:69#SGI ) )3+I&  Ai ;@ JK)PX@ qKpL@ pLY@  +3773zhF PX9\ 9JK)PX@ qKpL@ pLY@  +37737'\ hFP8X' #/;KPX@. g e     gqKpLK$PX@. g e     g]qL@3U g e     g]MYY@.10%$ 750;1;+)$/%/##    +!5!3!!"&54632!"&54632"&54632!"&54632hALB  &   TLSL" !!  !! 4!!!!LIfK)PX@ goK_rKpL@ggoKpLY@  +33"&54632"&54632L>@C65/ c@  JKPX@c_oL@gW_OY@   +"&546325%%5"&54632|P6;;&51=P@MJ~~ gc_wL32972=3=&$  11 +.5463232654&'&&54632#"&'&&#"7"&54632)8 &# G;&4   ' 9"  "(.85?   07 ;%49 0+%&'&&77Ew33!"#|)N)S!33wE")N)|# ( 5@KOSWf@* JHYXGe e  g    egee e]oLTTPPLLBAcaTWTWVUPSPSRQLOLONMGFAKBK=;760/.,(&"! 55  ! +"&547535!5!"&547!5!&54632!!'3654&#"2654'#5!5!535654&&54632 n6$7$$E$/* ! + ¶5#O  'd++++++% + $$ + % o  U++++++  #N&"4'T@Q    g _wK _xL!  %# '!'   +"5432"54323"54323"5432"543299:99:99:99:99:a;<<;;<<;;<<;;<<;<<<<5'T@Q g  _wK _ xL!  %# '!'   +"5432!"5432"5432"5432!"5432n99:&99:99:99:99:a;<<;;<<;<<<<<<<<<<<<5@2 Je]pL +'5'7#53'75373#';?~,~~,~?,~~-~-~?,,?~,~@GU]M +'7#5!!}/445Y #/I@F  g_qK_ xL%$ +)$/%/##    +"&54632"&54632!"&54632"&54632C       q   !!  !!  !! 4I@F  g_wK_ xL    +"5432"5432!"5432"543299:99: 99:99:a;<<;;<<;;<<;<<<<DFy 3+3@U]M +773NNd GK PX@g_tL@gW_OY@  +52654#52d'D1<<'" B(8227  ư3+ u 3+{oHKPX@_rLKPX@W_OKPX@_rL@W_OYYY@  +77"&54632{-:|.k34>&0+7%SRT$>R0+7%SRT$t@Ht +7:|.k51>@;J~|c_wL&$  11 +.5463232654&'&&54632#"&'&&#")8 &# G;&4   ' 9"  "(.85?   07 ;%uBK)PX@eqKtL@etLY@  +33#7$1$-  3+ yx58@5_wK_xL    +"5432"5432!"543299:99:o99:a;<<;<<<<<<<<H] KPX@8t^]PBA4 3  J$ IGKPX@8t^]PBA4 3  J$ IGK"PX@8t^]P BA4 3  J$ IGK-PX@8t^] P BA4 3  J$ IG@8t^] P BA4 3  J$ IGYYYYK PX@Q ~   ~  ||||| crLKPX@U ~   ~  ||||| crLKPX@Q ~   ~  ||||| crLKPX@Y ~   ~  ||||| czKrLKPX@_   ~  |   ~  ||||| czKrLKPX@e   ~  |  |   ~  |||||czKrLK"PX@e   ~  |  |   ~  |||||crLK-PX@q  ~  |  |  |  ~  |  |||||crL@w  ~  |  |  |  ~  |  ||||||crLYYYYYYYY@ ɼ&(,,,-. +70&&'667.546327.54632661.763270&&5463270&&5463270&&5463270&&5463210663266322663212663212663212663212>3216632&30                &  %&#) %$' ++ -, +,'( %/"60 )&/ ">:  5/!)%     )%  / &0  "+ 1!     %      #  $       &l@U]M +5!44Mt'""M&"3+33+#4@1]oK_zL    +#5!#7"&54632߼s55#!@]oL +#5!#߼55<O$@!a]oL +!%!!<{O{52 #/;_@\ J  g_wK_ xL10%$750;1;+)$/%/##  +"&54632'7"&54632!"&54632"&54632.2.45.2.[^   .65/4..6   @GU]M +%!5!#}44iWGx@S*?@<J~_wK_xL! &$ *!*%- +76676&&'&&546632&&#""54632'6S )'<(9G" Q4%($*)%H:@Y/?A.,8%*I84!23~& 0@-Ja_zL      +"54632&&'734%(% [3"2354 #UW&x|WK&PX@]oK_zL@g]oLY@  +!#7"&54632xw5x|@]oL +!#x5xHKPX@_rLKPX@W_OKPX@_rL@W_OYYY@  +'7'"&54632Dڷk.|ƅ>&0+'b$S%R%S$>R0+'b$S%R%S$t@Ht +'7@k.|518@5~|c_wL,*'% 11 +&&54676654&#"#"&5466323276632A/8 (   3';G "& 9%; 70   ?58.("  "BK)PX@eqKtL@etLY@  +#533J71f*@'c_rL  +%"&&546632'26654&&#"3T22T33S22S3#8""8##9""92T34S22S43T2<"9##8""8##9"5C@@ _wK_  xL    +"5432!"5432"5432!"543299:f99::99:99:a;<<;;<<;<<<<<<<<cu,@)gW_O#"#" +7663232673#".#"c nK;ywr57@ 4 oK9zyt37@ MO$3%MN$4%5>@;g_wK_xL    +"5432"5432"543299:99:99:a;<<;;<<;<<<<FE #J@GJIGgWg_O"    +"&54632&&#"56323267#"&.!$/>0H:.$/>1G: "N5  "M6 F}#F@CJIHggW_O##$$$" +&&#"56323267#"&"&54632!$/>0H:.$/>1G:9? "N5  "M6 F&aOL_ _3+$@]rKpL +!!5!eCT!/^@ )JKPX@c_qL@gW_OY@#""/#/ !! +%"&&5467&&54632&&#"'26654&'4Q-D. a\/P!@"0+55E)P7 +3=:-'C(9G0#:S? #?6.O/A,- 7(*H #gKPX@ g_oK_xL@gg_xLY@ ##    +"&54632"&54632"&54632$$&&$$&&$$&&3 $%%$ $%%$ $%%$ t 3+)  3+ 2 3+33&   3+y'5 -@*_wK_xL      +"&54632"&54632o    Y   !! 58@5_wK_xL    +"5432!"5432"5432n99:99:::9a;<<;;<<;<<<< !@ H_tL   +"&'73267]l*bB@3!4^^PNNP`\;e0+7;>%@ 0+'7'77'$C**)@$@*+(-75#55-55#5\= #/;Gr@o g g  c _qK_zK _pL=<10%$ CA54.54>54.54667LAQ,,,,,,,,,,6];AQ,,,,,,,,,,6];,#,$&,+%%+-"2?;,#,$&,,%%*-#2? :&<FL@&54JIED? + *# JKPX@*   h gqK _oLK)PX@(   g  h gqL@0   g  h W _OYY@ >=('C@=F>F/-'<(<&&%$"!! +&&54667533253&&'667##2675'"&54675"2327&ByCxM=21="?1;: =23It,5p2pzgQ>jA7v/+m/> OpB D@EL F   9 & \gck 9eHEi<Pz:T*t$@!JU]M +&&573Y\ 65 49C AdD@6 JHeU]M+D'#7'373#73'7#'#3DEEDCFFC-c22c--d22duxyuuyx,NVWNNWVz*/0+7'&&'6'6&')N)"Ew33!"#*#"!33wE")N)Qy8N P P3+7M P P3+Pb4$@!U^N +33P@:b$@!U^N +533@:~HP4@]oL +3#P:@]oL +#53~:H(bI'  b&  KPX@a]rLKPX@eU]MKPX@a]rL@eU]MYYY@  +%".54>3!!"3!4hT32Ug5/XE))EX/B<54.#!5!2#/XE))EX/4hT32Ug50/,,/0B<33"3|R/7 "@5#( 1/  ~[ +@ 8F (d2<E$x)2 -  OE;,1@.Jgc_IL,+%$#" +526776675&&546776654˜3"#!)) 1/!% }S/8 ">7~E#y)1 ,  N E\ Q  7F!(^7=5>"@a]IL +3#3 YyYBB>"@a]IL +73#739YyZB:BB;/@,~IK_NL  +73"&54632@Bgj@!#"n**;'  q 4@1~W_O       +"5463230""!j?BC.),.n5> @IL  +&&54673\ h`NVp~1|Ca]Cy3> @IL  +6654'3=Vn/C76654&#"'6632"&54632g&'5"$<"T(DQ>5 "<"#"%4*3'#B@@8M%!*)h2 'D@A$%J~gW_O "  ' '   +"&54632"&5467>733267" "DQ=6 "G&'5##<"TA*+'@@8L&"&4*3'#B[ &@#W_O ""+76632#&&#",~GSr 5 OB4hS=MC'1)/^< `!Y$KPX@ ! " J@ ! " JYK PX@!n]rK _ xLKPX@ ]rK _ xL@$]rKpK _ xLYY@ $$ +"&547###?33733#32676J =dXcSZ>4D4>! 2 4A '#+(&ozzzC ! C "2@/~hoKpL""!!$ +#7>337332#76654###7#"3Ed.Z.Q_( )],6Z5DV1 2HrB9Z2-7*}.S7X=@: ee ]oK pL%! +37#737#7332##3#32654##(WWWWJplKhTNGlvZAYL\SNOwAYAnL\h-!A@>~]oKrK^ pL!!  ! +3332673#!32#654&##qQbJ]hQh>hO[[_860;1;+)  // +"&''7677#"&5463232#"&'''3267376654#"326654&##77]X[ I]9DJ43!8DC.%% Z1Y@C9$81'  08q+T SN:/J;Hn=8GM1')/I'RW$PRHK? N  =#$@/+%2p#ZOKu/+|@ "JK PX@'n~_oK] pL@&~_oK] pLY@++'12 +#73&&546677363273&'#7&#"#733 8EB}X<<(#&&-53 '^j6@4ICO&I 6AC'1N$@..Q!4AYP^c+I4=V.jf)7|x1554&''5#'7D% T1 ;G(%H!0+5'! D)G@j+Ӵ">5 T T3+IU5K#PX@ ]L@U]MY@ +5!I 44,\@ JKPX@rK`pKtL@rKpK`xKtLY@%% +33266773#7##"'#XG !%"ME3VrH 2B)7 +"%/jWc3!.0. P&8J\m~KPX@8   h g_wK _ pL@@   h goK_wKpK _ xLY@Kon^]LK:9('xvn~o~ge]m^mUSK\L\CA9J:J1/'8(8 &&  +"&54>3232>54&#""&54>32!"&54>32!"&54>32%2>54&#"!2>54&#"!2>54&#"7< +B.9< -AN '&7< ,A.:< ,B7< ,A.:< ,B7= ,B.9< ,AK'&x'&y'&JGNRG+GBOUJ.6V'=B:)%$8A<PJFORF+GAOUK.JFORF+GAOUK.JFORF+GAOUK.B'=C9)%$8A<P'=C9)%$8A<P'=C9)%$8A<P P P3+K>WP ,@)Ue]M  +5#53533#ll4ll>o4oo4o$@!U]M+#7!3'ZPz6l H@E JIeeU]M +55!!!7#!5!=6-KU?b77q1>4* ˰3+`/ ʰ3+<# ʰ3+3 ;@8  JgW_O  +%"&5466327'26654&#"esʂ {ZjUt_ig oH_@^^Z^[[&A@ 1 >2 ? J~~   ~g  g g  W _ O('<:64/-'A(A!&& +"&546632373#7#32>54&#""&546632&&#"3267%3%H4 #-E//O") /S:G-Q7.%0>&*/979hB,8$6#5;"2N(" A?A=b: 7 WF'" 9 =&J@ ; <* ) J~~   ~g  g g  W _ O('@>97.,'J(J!&& +"&546632373#7#32>54&#""'53254&'&&54632&&#"%3%H4 #-E//O,) /,>%6?)!A4"8( +G979hB,8$6#5;"2N(" CA-+,5 5 )#17Q7t@q4J ~ ~g gW_ O 3210-+'&7 7 +33"&546632&&#"3267"&546773326773#7#QO@:G-Q7.%0>&*/(2*G,#BDF;26k?A=b: 7 WF'" 9 ,)%AO.!7&r&S & K@H  JggU]M+35&&546753&&'67!%IORFBB..1524,.,,l[Zjlh3 4w<; P>@R(&@#     JK PX@/  e e  U ] MK PX@3   e e  U ] M@/  e e  U ] MYY@( +!3#'#!33#!!#3#3'4&'PlX8c bPd9a^g@q<6A   3rX  MMB C7w&r)MLM(A@>J~_wK_xL$"((' +7'66327676654&'"54632H$ 0X6RW>4 ,"1#$4%(% DUH+FB&&+ "C!(.n4!23(7" JK PX@7n   ~ f  g  W _ O@6   ~ f  g  W _ OY@*)1/)7*7(('&%$&(+3#73733733#36632#"&'###%2>54#"M MXX  $U8AP#D`<6C!Br(A.S!E:#1X?aaaa?%2+,?\ZGe;7%RX?1Sg6l/Qh90<#P@MJeeeW_ O ## +"&'5326654&##77!737!7!3*^#&\.FT%K@NUo?T.H(;4FPPGGVXBj?,vk}@8D? bR e J  ~  ~   ~  ~  ggg  h  gW_O~~|{us[YKIC@20-,*(#!kk+"&&5467&&5466776610&&#"327#"&54663232663206322&&546321#0>54'6654.#"227'"&#"767&&'72654&'"#"&',20H*A! !+   #(     " 2C+G2 $"e= 2 -$(% +b    yt$![040 )& $:!Y5)) )e  )  0/GU'BP(4$$%%2 7X!:$)A:%)> 2_ " 4+ V92U+4)IJ@G J~eU]M! +33273#'#7'#32654&##)QaE_E[*]^/w>NNd[ECLʵMrOPkkvsWE=0cG@D~ ggU] M! +!##35332!6654&# hBB}Aofbs$LLgdcu<YGTKJ)o9i#W@T ! JIH~eU]M!+3327'7###33&##4'66)-%0\Qavbf3A>NNn"L"dF@F4-Dr*tMr'Hsm; Q ,8c%:_@\51)J~ ~gW_ O&&&:&:43-,+*('%% +"&'532654&'.54632&&#"733#5467###57'(((1"G;3-E)(47M^^a[@e5`c 5 )#00 1 2+,34`/ (N\jxT@Q6*$ KE?J   gW_ OsqecWUNMIG$!'''''(!+53267.546323267.54323267.543233#"&'#"&'#"&'#7>54&#">54&#">54&#""F#?>~% I$"G"}}$G$"E ! ~}% D#7U !V67U !W66V !S4 !%% x $$ x %%  3 "X['sm'XV%  !X\''ZW"  $WZ''ZW" 3jOQ$TRRT$QOOQ$TRRT$QOOQ$TRRT$QOjT@Q ee U ]  M +#5!#33#3#3333ve fӔB?j*66`6Z6d6`6oi/@, JHt+3'736673#':X'˰&c_ g>y:-L!B$O/6Q*P^T@QXIJH~ggW_ORQQ^R^DB97.,(&PP +"&&7667&&54>16676632#"&5463232>54.#"'2654&&'1Q."!&89&*2 (Y)R'?S)$FhES\*&*@(3B(.'.j40Z%50CH$7&62U62g0+\5:bK4'OaA46\#FN(@%JU]$L+!#533BnB-PN )@&JU]$L +!'#5353BĪBPN )@&JU]$L +!5#533BBKPN )@&JU]$L +!#5353Bb BP1$@!JH]$L+373?C P@JH]$L+373#=BB P%@"J^$L+3733?sBnP  @ J]$L+3753#>BB?P @ J]$L+3773#5>BBzP @ J]$L+3753#>BB0P@"1%@"JH]$L+3'753,CĻ1P&#@ J]$L+!'773-BU/P"$@!JH]$L+!'73,nBƸ2P( LJK&PX@]%K]$L@e]$LY@ +!#'73530Bɳ/P& %@"JH]$L +!5'73(kBsK4P&"@J]$L+!73.:B^.2P1%@"JH]$L+3573hBiSP '@$JH]$L +!753>B},WP -@*JHe]$L +!5#733;B7P '@$JH]$L +!773ԠBBPz  '@$JH]$L +!5'3>BrwP @ JH]$L+3'3#'X>ԠBBPN.@+J]$K]$L+3533#NBBBnP-N /@,J]$K]$L +35353#NBBBfPvN /@,J]$K]$L +35373#5NBBBPN /@,J]$K]$L +35353#NBBBqP1@J]$L+3'53#NנBBhPSi@J]$L+3'3#N<ܠBB xP CJKPX@]%K]$L@e]$LY+3'353##N;զBBwP @ J]$L+3'3#5P>BBPa- @ J]$L+3'3#'N<٣BB$P1"1@J]$L+3'73#5N,CC1P"@J]$L+3'73#N,éBBn2P&#@ J]$L+!''73-ȠB/UP& @J]$L+3'753#N(ȠBBk4KsP( *@'Je]$L +!5#'7330B/P&"@J]$L+!'3.hB2.^P1@J]$L+3'3#N8CC#i$P #@J]$L+3'3#]:kBB!P&@J]$L+3'3#N4ҢBB&i/P  @J]$L+3'753#P:˭BBy"]Py @ J]$L+3'3#5'N4ҢBB%iP' #@ Je]$L+3'33##_8BB#e(PF%1!@J]$L+3'73.CS3P'$@!Je$L+!#'73/n0P.&@#JH]$L+!'73'ɗB7q2*P% '@$JH]$L +!''753-ɠB2P% '@$JH]$L +!5'73)ɠBrx3sP% '@$JH]$L +!'73*ɠB93P1!@J]$L+373>CvGP@J]$L+373#=BBuCP%@"J^$L+3733>mBvnP @ J]$L+3753#=BBu9?P @ J]$L+3773#5>BBvzP @ J]$L+3753#>BBv!0P@NKJKPX@]%K]$L@e]$LY@ +!#5373}æBTnBPNKJKPX@]%K]$L@e]$LY@ +!#533vBBPN LJKPX@]%K]$L@e]$LY@ +!5#533BOBPN LJKPX@]%K]$L@e]$LY@ +!'#533B-B#P1"@J]$L+3573:CP#@ J]$L+!739B|#P!@J]$L+!'73:mBxcSP $@!J]$L +!7539B"@XP *@'Je]$L +!5#733:BP $@!J]$L +!773:B2P%1"@J]$L+3'73.C+1&P'#@ J]$L+!'73/B/0$P%!@J]$L+!'73-jB21 P% $@!J]$L +!'7753/B͠/P%"@J]$L+!573.;Bi1P" *@'Je]$L +!#'733Ȥ0BF-(P"1!@J]$L+3'3HGgqK_zL!!  +"&54473326732#4&#"#66b6F4$,.-7S\6F4$,..7T^97  !H>397  !H>D ,6KPX@10J@10JYKPX@$_MK_NK_NL@!_MK]JK_NLY@.--6.6)'   +"&5467&&546326673#'>54&#"267'HZOJTN=L)F+c$ W;$Qf)$T1!%(';p*<0KH?T?>R>7(:-=5X"j6#g ' *%,6.%-3"7 3+wj%qN~^"C^v^7RQ^J9^K?^ME^/Okb^Q^LL7J&dD@U]M +D7!V~GG-TT2dD@'U]M +D73#73o#O##O#T^c 3dD@( Jt    +D.'53#.'53+% ` '+% _ &^68 %M" 68 %M" ^K GdD@<I~gW_O      +D"&54632"&5447332673b-#&6F4$,..7T'-#~97 "#H>^0dD@% GW_O(" +D6632#4&#"DT?6F4$,..^H>97  !yJ4C ְ3+o4Cv ְ3+V& ZdDKPX@noU^N@U^NY@  +D7#7373Jn mB)A*8dD@-JW_O  +D"&'532773" 0 R =I6?;H*8dD@-JW`P  +D"&5467733267 /9 Q" "//  I]Q 'dD@W_O   +D"&54632#&#*Q;jN ڰ3+CO 3+K# &dD@Jt  +D5>73K S", 59 6;Zzq'P4 3+&uQdDK PX@oU]M@U]MY@  +D7!#7#$c$BڪnnOndD@ JKPX@nW`P@W`PY@  +D"&546733267332673#"&'-16,%/-&6'6%& !)( ) " * "%4#.9cK ۰3+8EJ ڰ3+2GQM 3+"FA f 3+HfQ 3+ c<L 3+f&dD@U]M +D7!  @@";JOQp p3+;I 3+S?&dD@U]M +D%7!FFo0+''7m$%<=dD@t +D3N-:0$Gc 3+&uQdDK PX@nU^N@U^NY@  +D73373$BB$ڪnn5'2dD@'eU]M +D73'37#++WW5^OthdD@  JKPX@oW_O@W_OY@!!"" +D6632632#6#"#6#" K06 7(06 6%0 7&;9##)) B "B "; 0+'7'77' !H/3/H"H/4/;*<;+<<+;<*;@b0dD@%gW_O +D72676&&7663" !P: "O@3&,#/2$-#0^ հ3+^zCD#^v}P7QdDK PX@oU]M@U]MY@  +D7!#7!$$BPnn"G-48 W 3+b(NdDK PX@oU]M@U]MY@  +D7#73@w 'x<9CdD@8JHGWg_O"'"$ +D'7&&#"#6632732673#"&'7-$ 4:+ -! 5:+ 9;>B 87>B A !-[dD@P gg  g  W _  O#" )'"-#- ! !  +D"&54632663232673#"&&#""&54632z:+2* 5:+/+ d9">B>Bm"]&V/WdD@Lg h W  g `   P//-+'%$#!$!$! +D63232673#"&'&&#"63232673#"&'&&#"<V" 3R& PV"  3R&  l l l l %b 0dD@%JHGU]M +D'7377#i c j c\\>>\\>b%dD@Ht +D7#7#};pG;x__xe '/7?GKOW_gowױdDKPX@6 e 754 e  9 8  g;:g=<gA@g?>e!C B#g%#E$D"+#"g)'G(F&*'&g/-+H*,+*g20,..,U20,,.^K3J1I.,.NKPX@54  ~6 e 7 g  9 8  g;:g=<gA@g?>e!C B#g%#E$D"+#"g)'G(F&*'&g/-+H*,+*g20,..,U20,,.^K3J1I.,.N@54  ~/-+&+-&~6 e 7 g  9 8  g;:g=<gA@g?>e!C B#g%#E$D"+#"g)'G(F&*'&g+H*,+*g20,..,U20,,.^K3J1I.,.NYY@ɤyxqpiha`YXQPLLHHA@9810)(!  }{xyuspwqwmkhoioec`gag][X_Y_USPWQWLOLONMHKHKJIEC@GAG=;8?9?530717-+(/)/%# '!'     L +D53#!5#53%53"5432"5432#"5432"5432!"5432"5432!"543253!53%"5432!"5432"5432!"5432"5432!"5432"5432#"5432"54325353!533353f_gLO;NQ6_5>y|b;g566fz.6ff6f66p.F3VF.p6gg666N0dD@% JU]M +D5667&&'53., 6886N3  2 D S& 3+^K BdD@7~gW_O "" +D6632#4&#""546325S?>=6",.-P-#H>EA"#g-#&e!# 0+''7'7731/12*31/1221/13*21/13p0dD@% JU]M +D.'5>73 6996 ., D 3  2(0dD@% JU]M +D5667&&'53|., 68863  2 D %dDK PX@ " JKPX@ " JKPX@ " J@ " JYYYK PX@U]MKPX@~U]MKPX@U]M@~U]MYYY@%% +D5667&&'5375>73#&&'., 6886 D 3   3  2 D  @BB@ B@kX+ 3+$qNK"dD@  Gt +D'7'7'37'j83F> F >F38*0 B"FF"B 0*@v+VdD@KJg  W  _O! '% +!+  +D"&54632632#"''2654&#"32654&#"1<<1891<<187    8227''7228((2TZdDKPX@noU^N@U^NY@  +D7#733i{"3{"TCxCxd( 1dD@&W_O    +D"&'332673QDpb;I>_]7>8=a[K 1 13+^&dD@U]M +D7!^GGSpN a 3+_4dD@)Wg_O#"#" +D663232673#".#"aD3[V[47; 6]B4\VZ47; _A?"C=$X .dD@#W_O "" +D6632#&&#">wDpb;a[_]7>8=N%3.dD@#JHGU]M +D5!7!5 [}><>\S40+''77v"v"SA@?LA@?T$dD@GU]M +D'73#&"T?KGN0dD@% JU]M +D.'5>736886 .,N D 3  2}%dDK PX@ ! JKPX@ ! JKPX@ ! J@ ! JYYYK PX@U]MKPX@~U]MKPX@U]M@~U]MYYY@%%  +D5667&&'537.'536673., 6886 3   3 3  2 D B@ B@ @Bo^d'L?M?3+:^c@U]M+7!^GG:^VLH^dLw# !dDK(PX@  J@  JYK(PX@Wg_O@+~~Wg_OY@ !!    +D"&5463256673"&54632 "X9d #C P% "Q#"w # !qdDK(PX@Wg_O@#Wge_OY@ !!    +D"&54632&&'73"&54632 !U #C#T #T "^'dD@Jt +D7>73#&&''bdXd[o8/  ^721761372##a1",UdD@J+ Jg  W  _O$#*(#,$,""  +D"&546326632#"&''27&&#"2654&#"*76+45+55+34$ # a:/+<$$'9.)>#% (18 ! 77TH)dD@ Jt +D&'773667=8( 21'<T8.# #4wy #DdD@9gW_O ##    +D"&54632"&546323"&54632 #""|  0+'7'77''7'77'$C**)@$@*+($B**)A#?*+)-75#55-55#57-75#55-55#5ACdD@8 gW_ OAA?=97$$"$$$$$ +D>32>32>32#&&#".#".#"!8+ + *$$* + +8!A!&."'..'".&!C?)********)?CEI********IEq'dD@JU_O +D"&5467734,/F&" d_ - ,dD@! JU_O +D"&54773"&544773",/F,.F&" n_ 9&" n_ #(dD@t +D3N) #( dD@t   +D"5467734"$fN~%41 3c:C 2dD@'U]M  +D6654&'3!&&54673#( <!# $F#( cF&/.&G.%HF&/cC )7JdD@?U]   M***7*710))#"  +D6654&'3!&&546733&&5467336654&'3;#(<!# $F#(O $F#( #( <!#cF&/.&G.%HF&/.%HF&/F&/.&G N 3+hFG{l l3+hGEl l3+ G|l l3+hFG&l l3+ GIl l3+lG l l3+GEgRlG l3+3+ FGSl l3+ GM(l l3+GBgXlG l3+3+lBGZl l3+hGl l3+iGl l3+hGl l3+o  3+*[1I'.dD@#W_O#" +D6632#.#"IBJl:D{VUPJ[-( (+h/GdD@<$I HggWg_O$$$$$$$" +D76323267#"&'&&#"76323267#"&'&&#" *2%#- )2&".0 (4%"- *2&!.g:$ :# :$ 9$ hGl l3+hFGl l3+hFGl l3+hGl l3+h-FGl l3+hFGl l3+lBGl l3+iDGl l3+lBGl l3+lBGl l3+iEGl l3+kHGl l3+ FGl l3+hFGl l3+lFGl l3+lBGl l3+"BGl l3+lBGl l3+hBGl l3+"BGl l3+iEG`l l3+h CCdD@8JeW_O +D"&546633##7#"3267(18'G-(-j&0h((&?&B- hFGl l3+hFGl l3+lCG Ml l3+hG Nl l3+lG Gl l3+iEGl l3+lCG Tl l3+lBGTl l3+lBGXl l3+lBGZl l3+b  3+%  3+'P 3+#R 3+NL1 3+NL$ 3+K Z 3+T#1%@dD@5gW_O!  %% +D"&54&#"3"&546323265441=! 2<=21>  1>=T91$""0;2/=:/ #!"1;10=80dD@%JgW_O$$$& +D76654&#"327#"&546324 &-!  ,@/-2@4V/-1/-5G45*VAWZdDKPX@noU^N@U^NY@  +D7#733m8.m7CxCxSkK 2dD@'U]M  +D%6654&'3!&&54673 #(<!# $F#(kF&/.&G.%HF&/ +@(W_O      +"&54632#"&54632 ##  @W_O   +"&54632.$&-#k @ Jt  +.'53Z,% ^ 'k68 %M"  k @Jt  +5>73 ((d7?k 45 :9|O 3@0 JU]M    +5>73#5>73*'Z 7?)'Z6>| 46 99 46 99r!@ Jt +5>73#&&'76U27)=r 59'O 0/r!@ Jt +&&'536673#27)=:76r'O 0/ 59y*@'HW_O  +"&5447332673U6F4$,..7Ty97  !H>uF 1@.gW_O      +"&54632'2654&#"z0<@,0=?. u722661372s1,@)Wg_O"""" +663232673#"&&#" :,2) 59+0, s>B>Br@U]M +7! rGG']Pkq 3+^Q* *  3+wFT<$ WdDJKPX@nW`P@W`PY@   +D"&547733267*"*I  $# ?1 :v:]dDKPX@noU^N@U^NY@ +D"&5433632#C,+D:;.%=sc,dD@!Wg_O%$!+D732676632#6454&#"#s *E5,:?$%b8c? ,, ]idD@ Gt%+D&&54632;;" :]8%!  ]sdD@Gt*+D5654&'&&54328  /!;]%  $!&85r2dD@'Wg_O"""+D663233#"&&#"D B566=&9T@4 @:>9B:QTdDKPX@oU]M@U]MY@ +D"&'463!2#"&7!:  hFGl l3+hBGl l3+5lG(l l3+ BGl l3+hBGl l3+hBGl l3+hBGl l3+lCGNl l3+^$k'dD@ JKPX@noW`PKPX@oW`P@W`PYY@ %#+D7#"&546773326773M" ( @ #>\kF  #( >o!jdD@ !JK PX@nW`P@W`PY@ +D'7&&5466773'76654&'>6:.S8B7:/S70.6[/8 I;8X4 G99Y6M;$.O;#-hFGRl l3+: HKPX@oU]M@U]MY@   +"&5433#%C:;5hFKPX@nU^N@U^NY@ !+53632E,+Dh5.%=,D/;fE/;E/;/;/;x/;f/;;qFE3+E3+3+װ3+3+3+3+q3+(,NdD@C~|eU^ N  +D7!#7!73!730h0H(0HH0L g #'+/dD@~~! f  e     eU]M,,(($$  ,/,/.-(+(+*)$'$'&% # #"!   "+D7#73733#7!!7!7!!7!7!!7!33333( 0 ^ ; c ; ; c ; ; c ; cC0CC0CC0CE00000000000000G;;;iEG,l l3+lBGil l3+lBGl l3+lBG>l l3+lBGJl l3+hFGDl l3+hFGl l3+h FGDl l3+h$FGFl l3+ FGl l3+hFGFl l3+hGGl l3+hFGHl l3+hGl l3+_^h&MM FGJl l3+lGKl l3+5lGL(l l3+iGil l3+lGNl l3+4lGO(l l3+ G@"l l3+lFGPl l3+kHGQl l3+iEGRl l3+?GU2 3+lFGUl l3+ lBGWl l3+hFGVl l3++hsGWl l3+hBGXl l3+lBGYl l3+lBG[l l3+lBG]l l3+\G9 )&f 3+g ʰ3+ At@ ! 5 >JKPX@ _wK_xK_tL@c_wK_xLY@<:41%# AA +"&&'&&'&&'5326654&'.546632&&#"#"&'32672="S6-L.5A&;!@k@8U&"N)>N."+A%w   ,,0*E('X:.(9%2@/B]0L@:("2B1kn - F =^@ JKPX@]oKpK_tL@c]oKpLY@  +"&&'&&##7!7!3267H2>%).D >:7#$ * <*4&F4PG<5)-J1 "@ JrKpL  +#77'73 ?X9 AX: 112g0%p JKPX@grK `xL@!grKpK `xLY@%%  +"&546736632%3%2654&#"P^?Y26QR-]qXr`>7321* KO4*ID2T2 >?),!%+/"$/KPX@ J@ JYKPX@"h _rK_ xLKPX@/UgrK _zK pK_xL@0fgrK _zK pK_xLYY@.,'%$$%%%# +333>32##3267#"&547#326654&#"rW.zFe?LMAn;>&D(&I3]e|3#%0Y?j@B;5U3 =GKm]/1)!Y"&!H7f'6@ #JK"PX@]rK `xLK(PX@rK_zK `xL@*rK_zK `xK `xLYY@)(1/(6)6! '' +"&5467332667736632#"&'#%26654&&#"?JFYH &"NE1W@$^j"CdCF`>Tk/O/0(7Q,=FC(G+ %0jXo`=zd=@9:&OC~X9%K}K>D /@,J_zK]pL &% +#73&5466323#76654&#" o;F{PbqEAoMQ=93M+" LHiUKpaM2LA0SAD8b@>Y$?'bN@ JKPX@`tL@W`PY@   +"&546733267*&3!2!  ')#C#C!7f E@B  JIe]#K]'L +5!!5!#!'!6=K9UN77?w:>)%/!*3@   JK PX@.no  e _oK ] pL@,  e _oK ] pLY@31-+*($"!!1! +33733273#7"###732654&##32654&##)U<<(.SD,=gT<7<]W?Y8@Gw`PW9EReehwH8I[ HCCkC30CC0L,C709^ '^<F'k''P'<'*@1SR*<F9@1e7<FaGaQsI_QaSV V%X72222228KH))))DDDD!(HHHHH<T9OOOO\7)H8080808080804000000:+C3030303030<F3C7C7C7C7C280280280KH0KH0KH0KH0)e0!C0)0)0)0)0)0HCHCHCHC*C)CDDDDDUd2)))) )) (C(C(C)(CH30H30H30[Hb0=)=)=)WL'ZL,SLOC7OC7OC7OC7OC7OC7Xk9\\'28084093s]pn/ps2-2Qa0&&&!0732X)))*HD2)2I((H)7) Z\H`D\<0C73D@<0E(,#0C#0730(30b&=0H0&D@0E073D@30D@0)Z)KHDDd)Z2)>)27*X))v)))2)I(*H)7)KHZ>H(w((wZ)-)J )?80!10600MC7C7 Y30CC0k0U7/Mk7}7X)> > 0C02CC7)Xk9Xk9Xk9\<<pf<f<i xafPDD* xE''' _6k="UI7ODH22aKa_aqaXM'd))<E\%4I(k280MH80Or7))0C7b@LF-,_)_Q)Y)#`EH307\/7\)H0HG0G1b@KH0a8(G7*) =8*C$b*?Qb*?*2)}Z8&*])*6HX0KH0Zy\04DZ,v)Mv/L*C<W$<W$DM|* #*Y*]vDaS(D280280840)0((M)C7)C7H30H30H30K  >>>w/M*)> 7-C0B0T0HwIBsK.*fHQ0ZS* 9280280280280280280280280280280280280)0)0)0)0)0)0)0)0DDH30H30H30H30H30H30H30H80H80H80H80H80OC7OC7Or7Or7Or7Or7Or7\\\Cz1z{NLCP7*CRE=BKKH0!P;0C0*(!H(Gn73D2)DCHH0PC=)  %L,PL,ZJOP!7<>>@)X)0))((E280DH30OC7OC7OC7OC7OC7280280840HHC2)H30H30)X)0HC)w(C280280)0)0DDH30H30=)=)OC7OC7?*C)C0,B'280)0H30H30H30H30\U[012KHC$X!2)dHC0= 5'7808CC0C0 )0CC0-C7CC 73&\M jk7k7kCCd30+0-0>>( =LLC3(X@2 @UH))#0YOC0O000,,,$o@:NNxGxGG  ^GZ0<f<<pav ` \nons]((o0 * !q0GG8:lNNNNMNNpf<JJMM.@E-11"y010\0b L30H`0)<,BU*b ?0H0 7)CKHI(=KKHKHC0Xk94 06%KaP04.`, 3530$:B:K W<HCa?/mPBPNPN8dP(mP7P#OOOdRqPtPFph,{qTfYqTExGxTDTDE%H*-xE/BG9GxGnT&0nWnTx'RxY~J9Y0T.z&.OiLTJx0z.tJNACC0>kCC>LCGp&7CA3CC0kCC08080C00@C7qG&T9.sQ!4xExY<V$$:G9G9YxxGGnTTRx:nOx[_0!+!+S+. dTX)CX)CX)CKH0)C0)C0)C0)C0)C0)0)0# )0)>HC*C*C*CC*CDD2)2)2))))I(kI(k(C(C(C(CH30H30H30H307)C7)C=)=)=)=)ZL,ZL,*LLOC)JC%OC%OC7OC7(\0(\0Xk9Xk9\CL,980<0<0<0<0<0<0<0<022++++++P=TS=S=SCCCCCCCC=Sw=ySw=qSw1w1737373737373737+=S-=/SJ=DSE1E1303030303030=S=S=SD@D@D@D@D@D@D@D@RRR100000000-=/I=S=Sx1x1<0<0CC73733030D@D@00<0<0<0<0<0<0<0<0ii++++++CCCCCCCC=S=S=S1100000000d=fI=S=S11<0<0<0<0<0<0<02222iA**CCCCCEC@3C3*AAQ73737,7377.DDC3AAQD@D@D@D@==D@D@\\SGSAAA600000%S8<S*A@+';'fk,.De [aeaja_qDn:D'H'9'>k'#l2+''#H2KH'\j@1!OK+ 7)=8L*T])H0lk9 )0RUlxey``?A*#SzTL<0<0<0<0<0<0<0<07373737373737373D@D@D@D@D@D@D@D@73737373D@D@D@D@)(Qm*+3**+*E(EA' *I( 2W>>HT*Z!( &&!K2)2)2)6x)MHH7zj@xH H(Xk7)74-RH+!++`KKp(K2 =)G?-+/vqXG2)DO)(,#d030zO;' s2C,(d0V0u0000Yi300C!;C0099CCG70,:/d/&CCCE122800CC7~@@g------%/%//-/-/-/-/-333vvPPPPPPQ-Q-Q-Q-Q-Q-Q-Q-Q Q Q--Q-H;3;%./3/3/3/3/3/3/3/3/3/3/3<FFFFF=====Q!J'0"WI8x[! ,GwMoZ#*I*2*D*HHHv3wZZY)*HHY!XDE#.#ekudOED/ 73o1X5.*08Y7F_30T30EbM=+L  =C'030,#CC7k7k7qTBPT]*XK)2 dU^ER=/ QJ ]"A  ax 2m2 a aa=a&$(a!2)[8!!IC  W Wo 1CCD0C>32E;< 40>C}\8kCC,,3e0aae0e0o"^2t,O,C7Ck8kN#+"+"C80^uxx4{YP3TxGAAC**/9d'''''.<( ' #+ *,'9_"6a a@aaaa aaaaaJaua+a7a1aEaSa[a;aISXJS[+&7:1S:E&SS Saa"aaaaaaaa^6X""USi\'L;5554=5<564D5d{>>5''45\MM3##<E2WiSxx>>5'<f=5c5'F'F'F$T H) '545p;@\fL:*#Cz QMPMMPM(A999 X9DB& !i@iBtXXXXXXXXXXX9F<9KKa%B"tRRRxRRIIPRRKl4`3[=Q7= c(*7M",=)c=)J *8((D*NNNN "&"(&&#' NNNN""&&(&#'%'.%%%NNNN%'%%%""#""""'%'%%%??NNNN%GGGGG3%%%%%%%%"%%-****+NNNN*073%~b-JoVH9OD9>]*CKZq.2" J;o5#}-bbepk$KdSNo::H_ESq)*Ib'S ****Ak vsB5og_54? +g\7Nl')61Z(Z(Z(Z(Z(Z(Z(Z(NNNNNNNNNNONNONTTTT LpH4l| X H h @(d@|DDXtlxp t8!!"#P$<%P&&'H'())*0+ +,-<-.///001123,3,34`556h678t9::;(;8>? ?0??@d@AdAABBPBpBBBCC$CHCCDD4DXD|DDDE EEEFF,FPFtFGGGGHH8HIIJ J$J<JTJlKLL(L@LXLpLLLLMMMMNN N8NOOOOPPQQ QDQ\QQQQQRR(R@RdR|RRRRSTHTlTTTTTUVDVhVVVVVWW4WLWdWWX<YY<YTYxYYYYYZ Z8ZPZtZZZ[ [D[h[[[[[\\\]]0]H]`]]]^X_@_d_|____a(b8b\btbbbbccc@cXcpcccccdd0deeeeff(f@fdf|ffffg g$gHg`gggggh h8hijl@ldl|llllmTmnnpnoDop8pqrr,rLrprrrss,sDsTsdsssstttu0u@uPuvvhvxvw wxxxxyy0yHy`yxyz{t{|}p~~0t0dp ( 0$DTx<`PXt$4tpL 0@ H8$\$<P`p,4Lph0tH( , D\ \|<0˜LÄü,Ĩ4ŘƬTǠhhhhhhhhhhhhhh`,DTp<@Xpш Өh8լ $h8۸0Xިߠ\dt4 0H`xH D\|@Tx| 4$ ,p<0Ph p`D    ` <   0@d|P| ,Xh$<,Ph@Xhx,Ph 8    !"4"#P#$@$P%%''()p*D+X, ,-.@./\0(081X2|22223 3$3H3`333344$4H4`4444455@5`5x555566,6D6h666667$7D7h77777888@8X8|88889 989X9|9999: :0:H:`:x::::;; ;D;\;;;;;<<<@>?@A<BLC<CD8DPDhEFFGHtIPIpJ<K0K@KLMMN N0OOPlQRhRSTTTU0VlWHWWX Y YZ[\P]]]^_`Ha8abdc@cdeDeefdgghi ijk@kklHlXlllllm m$m<mTmxmmmmnn,nDnhnnnnnoo4oXopoooopqrr(rLrprrrrss(s@sXspsst|u$uHu`uuuuuvv8vPvtvvvvww(w@wdw|wwwwxx0xytyyzl{|}~D~T~x~~~~~ 8\t8X44|(H4d`( 0P 0p,<LD8t(8l|(\HH0Px$l|l,„8DT@ŨȄ0@ψԜT|؀@dڈڬ(8HXۼܔ8Xݤ$Ddބޤ @`߀ߠ8\84|8Xh$PpX0|l|@P,<d,Pdt,,P`pTP<`$h T(0x@h\D<    ( L $ H l      D h   8 \    4X| 0Tx,Pt(Lp$Hl0Ppxpd|8 @!x"4#D#h$ &H&'X()0)+p,.8/01$2h3h456|78,89`::< => ?(@8A ABCDDEE@EdEEEEFF<F`FFFFGG8G\GGGGHH4HXH|HHHI I0ITIxIIIJJ,JDJ\JtJJJKK,KDK\KtKKLtMNN(NLNdNNNNOO$OPOpOOOOPP<PTPlPPPPQQ,QDQhQQQQRRR@RdR|RRRSS4SLSdSSSSST T$T<T`TTTTTUU,UPUhUUUUVVV@VXVpVVVVWW@WXWpWWWWXX,XLXpXXXXYY Y8Y\YYYYYZZZ@ZXZ|ZZZZ[[[0[T[l[[[[\\ \8\P\t\\\\] ]$]H]`]x]]]]]^^,^P^t^^^__(_@_X_p____``(`P`x````aaa0aHa`aaaab bHbpbbbbbcc(c@cXc|cccdd@dhdddddee eDeheeeff f8fPfhfffffgg<gdg|gggggh h$hHhlhhhi i4i\i|iiiijj(j@j`jxjjjjkk(kDk`k|kkkkl(lTlllmm0mPmpmmmmnn0n\nnnooHoxooopp p<pXptpppqqHqxqqrr r8r`rxrrrrss4sXspssstttuu4uLuluuuuvw wxxxyy y8yPytyyyz{L|| |8|X|p|||||}}@}h}~dp 8X|T<@XL\ `8Dd@$x|h $\(t@xXp4@T$h,Lx@4Ld| $<Tl,D\t4L0@DhlPhDLĈ| 40($XΐϐМ0X<մLظ8ܐ4ݰTް`l4xX$<pD`ppl(H0H,t$Tt||0x$0@X4Tt,(4Ld|         ,<\lt$HT !#`#p$ $%&&x'@(|()*,$-,.T./t/013 3l3|4h567P89p:;d<=><???@AxACCDEFtGHH HHHI IJPJhJJJJJL<N8PP,PDQS\SSTTT4TLTlTTTTUhUV$VVVWW$W<WX0XPX`XXXYY0YHYhYYYZ ZZZ[[ [x\\$\x\\\\] ]$]<]\]t]]^ ^^^^__,_P_`(````aab(b@b`bbbbbccce$effg$g<g\gthh4hThlhhiij\j|jjkk4kTktkkkkkll<lm8mPmpmmmnDn\n|nnooo8oXo|opXpq(qHqrXrstuvxxxy0yz{|4|}~ hL@`LXXT`,<L\ tXX,8@tXt4H`xh,P`L\ 0lLx|HxʴH̼ϰ8М4$xԄ֨ؤ4<޴ߌX$@d, <\LH `pH  ( $   $D@P,pD <\|@dhx4@`8 4  !!! !0!@!P!`!p!!!!"" "@"`""""## #@#`####$$$8$X$x$$$$%%8%`%%%%&& &@&`&&&'0''(@((())p)+\, ,-.80,0D112P23l4404h44556 646p7<7778P????@ @(@@A4BXBBCtCDDEEEFFGDGHtHItJ,JKKDL4MM(MHMhMMN NNOOPPQpS8STTdTtTTTU<U|UUUVWWX XDXTXdXXXYYHYpYZZ[t[\\p\\]D]^D__`_t_t_t_t_t_t_t_t_t_t_t_t_t`a4abd(dfgg$ggh0hi@i`ij$jDjkTmmnn\noo8oXoqLrsstv v$v4vx8x{||$|}}~Ht@4d< 0|t l ` Htl\T$hL\4xd P,t,$plP@$x(lDh0(x hP8,`<h,|\PD@(<Pdx$@ ,(xLPp\DTd(Hh d\p,L`p0Xà ȔȰ@x`P$ͤ(lΌ p4Ш8t҈ҘӘt`0|֠Hp؈hDڰ`ܼݠ,޼߰<`(`$d<`8\4X4X| 0TTt4l|<\$|,X0@d|$ Dh@d0Tx,Pt(Lp TlX$Dx P p   d    x  P    \Ll - m ^ ^  p 4|    ` D~ * ( B >V <  4fCopyright 2015 Google Inc. All Rights Reserved.Noto SansItalic2.000;GOOG;NotoSans-ItalicNoto Sans ItalicVersion 2.000;GOOG;noto-source:20170915:90ef993387c0; ttfautohint (v1.7)NotoSans-ItalicNoto is a trademark of Google Inc.Monotype Imaging Inc.Monotype Design TeamDesigned by Monotype design team.http://www.google.com/get/noto/http://www.monotype.com/studioThis Font Software is licensed under the SIL Open Font License, Version 1.1. This Font Software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the SIL Open Font License for the specific language, permissions and limitations governing your use of this Font Software.http://scripts.sil.org/OFL2   !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`a  bcdefghjikmlnoqprsutvwxzy{}|~    !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~                           ! " # $ % & ' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; < = > ? @ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ _ ` a b c d e f g h i j k l m n o p q r s t u v w x y z { | } ~                            ! " # $ % & ' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; < = > ? @ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ _ ` a b c d e f g h i j k l m n o p q r s t u v w x y z { | } ~                            ! " # $ % & ' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; < = > ? @ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ _ ` a b c d e f g h i j k l m n o p q r s t u v w x y z { | } ~                            ! " # $ % & ' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; < = > ? @ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ _ ` a b c d e f g h i j k l m n o p q r s t u v w x y z { | } ~  NULLCRuni00A0uni00AD overscoreuni00B2uni00B3uni03BCuni00B9AmacronamacronAbreveabreveAogonekaogonek Ccircumflex ccircumflexCdotcdotDcarondcaronDcroatEmacronemacronEbreveebreve Edotaccent edotaccentEogonekeogonekEcaronecaron Gcircumflex gcircumflexGdotgdotuni0122uni0123 Hcircumflex hcircumflexHbarhbarItildeitildeImacronimacronIbreveibreveIogonekiogonekIJij Jcircumflex jcircumflexuni0136uni0137 kgreenlandicLacutelacuteuni013Buni013CLcaronlcaronLdotldotNacutenacuteuni0145uni0146Ncaronncaron napostropheEngengOmacronomacronObreveobreve Ohungarumlaut ohungarumlautRacuteracuteuni0156uni0157RcaronrcaronSacutesacute Scircumflex scircumflexuni021Auni021BTcarontcaronTbartbarUtildeutildeUmacronumacronUbreveubreveUringuring Uhungarumlaut uhungarumlautUogonekuogonek Wcircumflex wcircumflex Ycircumflex ycircumflexZacutezacute Zdotaccent zdotaccentlongs Aringacute aringacuteAEacuteaeacute Oslashacute oslashacuteuni0218uni0219tonos dieresistonos Alphatonos anoteleia EpsilontonosEtatonos Iotatonos Omicrontonos Upsilontonos OmegatonosiotadieresistonosAlphaBetaGammaEpsilonZetaEtaThetaIotaKappaLambdaMuNuXiOmicronPiRhoSigmaTauUpsilonPhiChiPsi IotadieresisUpsilondieresis alphatonos epsilontonosetatonos iotatonosupsilondieresistonosalphabetagammadeltaepsilonzetaetathetaiotakappalambdanuxiomicronrhosigma1sigmatauupsilonphichipsiomega iotadieresisupsilondieresis omicrontonos upsilontonos omegatonos afii10023 afii10051 afii10052 afii10053 afii10054 afii10055 afii10056 afii10057 afii10058 afii10059 afii10060 afii10061 afii10062 afii10145 afii10017 afii10018 afii10019 afii10020 afii10021 afii10022 afii10024 afii10025 afii10026 afii10027 afii10028 afii10029 afii10030 afii10031 afii10032 afii10033 afii10034 afii10035 afii10036 afii10037 afii10038 afii10039 afii10040 afii10041 afii10042 afii10043 afii10044 afii10045 afii10046 afii10047 afii10048 afii10049 afii10065 afii10066 afii10067 afii10068 afii10069 afii10070 afii10072 afii10073 afii10074 afii10075 afii10076 afii10077 afii10078 afii10079 afii10080 afii10081 afii10082 afii10083 afii10084 afii10085 afii10086 afii10087 afii10088 afii10089 afii10090 afii10091 afii10092 afii10093 afii10094 afii10095 afii10096 afii10097 afii10071 afii10099 afii10100 afii10101 afii10102 afii10103 afii10104 afii10105 afii10106 afii10107 afii10108 afii10109 afii10110 afii10193 afii10050 afii10098WgravewgraveWacutewacute Wdieresis wdieresisYgraveygrave afii00208 underscoredbl quotereversedminutesecond exclamdbl nsuperior afii08941pesetaEuro afii61248 afii61289 afii61352uni03A9 estimated oneeighth threeeighths fiveeighths seveneighthsuni0394 cyrillicbrevecaroncommaaccentcommaaccentrotateuni2074uni2075uni2077uni2078uni2000uni2001uni2002uni2003uni2004uni2005uni2006uni2007uni2008uni2009uni200Auni200BuniFEFFuniFFFCuniFFFDuni01F0uni02BCuni03D1uni03D2uni03D6uni1E3Euni1E3Funi1E00uni1E01uni02F3OhornohornUhornuhornhookuni0400uni040Duni0450uni045Duni0460uni0461uni0462uni0463uni0464uni0465uni0466uni0467uni0468uni0469uni046Auni046Buni046Cuni046Duni046Euni046Funi0470uni0471uni0472uni0473uni0474uni0475uni0476uni0477uni0478uni0479uni047Auni047Buni047Cuni047Duni047Euni047Funi0480uni0481uni0482uni0488uni0489uni048Auni048Buni048Cuni048Duni048Euni048Funi0492uni0493uni0494uni0495uni0496uni0497uni0498uni0499uni049Auni049Buni049Cuni049Duni049Euni049Funi04A0uni04A1uni04A2uni04A3uni04A4uni04A5uni04A6uni04A7uni04A8uni04A9uni04AAuni04ABuni04ACuni04ADuni04AEuni04AFuni04B0uni04B1uni04B2uni04B3uni04B4uni04B5uni04B6uni04B7uni04B8uni04B9uni04BAuni04BBuni04BCuni04BDuni04BEuni04BFuni04C0uni04C1uni04C2uni04C3uni04C4uni04C5uni04C6uni04C7uni04C8uni04C9uni04CAuni04CBuni04CCuni04CDuni04CEuni04CFuni04D0uni04D1uni04D2uni04D3uni04D4uni04D5uni04D6uni04D7uni04D8uni04D9uni04DAuni04DBuni04DCuni04DDuni04DEuni04DFuni04E0uni04E1uni04E2uni04E3uni04E4uni04E5uni04E6uni04E7uni04E8uni04E9uni04EAuni04EBuni04ECuni04EDuni04EEuni04EFuni04F0uni04F1uni04F2uni04F3uni04F4uni04F5uni04F6uni04F7uni04F8uni04F9uni04FAuni04FBuni04FCuni04FDuni04FEuni04FFuni0500uni0501uni0502uni0503uni0504uni0505uni0506uni0507uni0508uni0509uni050Auni050Buni050Cuni050Duni050Euni050Funi0510uni0511uni0512uni0513uni1EA0uni1EA1uni1EA2uni1EA3uni1EA4uni1EA5uni1EA6uni1EA7uni1EA8uni1EA9uni1EAAuni1EABuni1EACuni1EADuni1EAEuni1EAFuni1EB0uni1EB1uni1EB2uni1EB3uni1EB4uni1EB5uni1EB6uni1EB7uni1EB8uni1EB9uni1EBAuni1EBBuni1EBCuni1EBDuni1EBEuni1EBFuni1EC0uni1EC1uni1EC2uni1EC3uni1EC4uni1EC5uni1EC6uni1EC7uni1EC8uni1EC9uni1ECAuni1ECBuni1ECCuni1ECDuni1ECEuni1ECFuni1ED0uni1ED1uni1ED2uni1ED3uni1ED4uni1ED5uni1ED6uni1ED7uni1ED8uni1ED9uni1EDAuni1EDBuni1EDCuni1EDDuni1EDEuni1EDFuni1EE0uni1EE1uni1EE2uni1EE3uni1EE4uni1EE5uni1EE6uni1EE7uni1EE8uni1EE9uni1EEAuni1EEBuni1EECuni1EEDuni1EEEuni1EEFuni1EF0uni1EF1uni1EF4uni1EF5uni1EF6uni1EF7uni1EF8uni1EF9uni20ABcircumflexacutecombcircumflexgravecombcircumflexhookcombcircumflextildecombbreveacutecombbrevegravecomb brevehookcombbrevetildecombcyrillichookleftcyrillicbighookUCuni0162uni0163uni0180uni0181uni0182uni0183uni0184uni0185uni0186uni0187uni0188uni0189uni018Auni018Buni018Cuni018Duni018Euni018Funi0190uni0191uni0193uni0194uni0195uni0196uni0197uni0198uni0199uni019Auni019Buni019Cuni019Duni019Euni019Funi01A2uni01A3uni01A4uni01A5uni01A6uni01A7uni01A8uni01A9uni01AAuni01ABuni01ACuni01ADuni01AEuni01B1uni01B2uni01B3uni01B4uni01B5uni01B6uni01B7uni01B8uni01B9uni01BAuni01BBuni01BCuni01BDuni01BEuni01BFuni01C0uni01C1uni01C2uni01C3uni01C4uni01C5uni01C6uni01C7uni01C8uni01C9uni01CAuni01CBuni01CCuni01CDuni01CEuni01CFuni01D0uni01D1uni01D2uni01D3uni01D4uni01D5uni01D6uni01D7uni01D8uni01D9uni01DAuni01DBuni01DCuni01DEuni01DFuni01E0uni01E1uni01E2uni01E3uni01E4uni01E5uni01E6uni01E7uni01E8uni01E9uni01EAuni01EBuni01ECuni01EDuni01EEuni01EFuni01F1uni01F2uni01F3uni01F4uni01F5uni01F6uni01F7uni01F8uni01F9uni0200uni0201uni0202uni0203uni0204uni0205uni0206uni0207uni0208uni0209uni020Auni020Buni020Cuni020Duni020Euni020Funi0210uni0211uni0212uni0213uni0214uni0215uni0216uni0217uni021Cuni021Duni021Euni021Funi0220uni0221uni0222uni0223uni0224uni0225uni0226uni0227uni0228uni0229uni022Auni022Buni022Cuni022Duni022Euni022Funi0230uni0231uni0232uni0233uni0234uni0235uni0236uni0238uni0239uni023Auni023Buni023Cuni023Duni023Euni023Funi0240uni0241uni0242uni0243uni0244uni0245uni0246uni0247uni0248uni0249uni024Auni024Buni024Cuni024Duni024Euni024Funi0250uni0251uni0252uni0253uni0254uni0255uni0256uni0257uni0258uni0259uni025Buni025Euni025Funi0260uni0261uni0262uni0263uni0264uni0265uni0266uni0267uni0268 iotaLatinuni026Auni026Buni026Cuni026Duni026Euni026Funi0270uni0271uni0272uni0273uni0274uni0275uni0276 omegacloseduni0278uni0279uni027Auni027Buni027Cuni027Duni027Euni027Funi0280uni0281uni0282uni0283uni0284uni0285uni0286uni0287uni0288uni0289uni028Auni028Buni028Cuni028Duni028Euni028Funi0290uni0291uni0292uni0293uni0294uni0295 glottalturneduni0297uni0298uni0299uni029Auni029Buni029Cuni029Duni029Euni029Funi02A0uni02A1uni02A2dzliguni02A4 dzligcurltsliguni02A7 tcligcurluni02A9uni02AAuni02ABuni02ACuni02ADuni02AEuni02AFuni02B0uni02B1uni02B2uni02B3uni02B4uni02B5uni02B6uni02B7uni02B8uni02B9uni02BAuni02BBuni02BDuni02BEuni02BFuni02C0uni02C1uni02C2uni02C3uni02C4uni02C5uni02C8uni02CAuni02CBuni02CCuni02CDuni02CEuni02CFuni02D0uni02D1uni02D2uni02D3uni02D4uni02D5uni02D6uni02D7uni02DFuni02E0uni02E1uni02E2uni02E3uni02E4uni02E5uni02E6uni02E7uni02E8uni02E9uni02EAuni02EBuni02ECuni02EDuni02EEuni02EFuni02F0uni02F1uni02F2uni02F4uni02F5uni02F6uni02F7uni02F8uni02F9uni02FAuni02FBuni02FCuni02FDuni02FEuni02FF hookabovecombuni0374uni0375uni037Auni037Buni037Cuni037Duni037Euni03D0uni03D3uni03D4phi1uni03D7uni03D8uni03D9uni03DAuni03DBuni03DCuni03DDuni03DEuni03DFuni03E0uni03E1uni03F0uni03F1uni03F2uni03F3uni03F4uni03F5uni03F6uni03F7uni03F8uni03F9uni03FAuni03FBuni03FCuni03FDuni03FEuni03FFuni051Auni051Buni051Cuni051Duni1D00uni1D01uni1D02uni1D03uni1D04uni1D05uni1D06uni1D07uni1D08uni1D09uni1D0Auni1D0Buni1D0Cuni1D0Duni1D0Euni1D0Funi1D10uni1D11uni1D12uni1D13uni1D14uni1D15uni1D16uni1D17uni1D18uni1D19uni1D1Auni1D1Buni1D1Cuni1D1Duni1D1Euni1D1Funi1D20uni1D21uni1D22uni1D23uni1D24uni1D25uni1D26uni1D27uni1D28uni1D29uni1D2Auni1D2Buni1D2Cuni1D2Duni1D2Euni1D2Funi1D30uni1D31uni1D32uni1D33uni1D34uni1D35uni1D36uni1D37uni1D38uni1D39uni1D3Auni1D3Buni1D3Cuni1D3Duni1D3Euni1D3Funi1D40uni1D41uni1D42uni1D43uni1D44uni1D45uni1D46uni1D47uni1D48uni1D49uni1D4Auni1D4Buni1D4Cuni1D4Duni1D4Euni1D4Funi1D50uni1D51uni1D52uni1D53uni1D54uni1D55uni1D56uni1D57uni1D58uni1D59uni1D5Auni1D5Buni1D5Cuni1D5Duni1D5Euni1D5Funi1D60uni1D61uni1D62uni1D63uni1D64uni1D65uni1D66uni1D67uni1D68uni1D69uni1D6Auni1D6Buni1D6Cuni1D6Duni1D6Euni1D6Funi1D70uni1D71uni1D72uni1D73uni1D74uni1D75uni1D76uni1D77uni1D78uni1D79uni1D7Auni1D7Buni1D7Cuni1D7Duni1D7Euni1D7Funi1D80uni1D81uni1D82uni1D83uni1D84uni1D85uni1D86uni1D87uni1D88uni1D89uni1D8Auni1D8Buni1D8Cuni1D8Duni1D8Euni1D8Funi1D90uni1D91uni1D92uni1D93uni1D94uni1D95uni1D96uni1D97uni1D98uni1D99uni1D9Auni1D9Buni1D9Cuni1D9Duni1D9Euni1D9Funi1DA0uni1DA1uni1DA2uni1DA3uni1DA4uni1DA5uni1DA6uni1DA7uni1DA8uni1DA9uni1DAAuni1DABuni1DACuni1DADuni1DAEuni1DAFuni1DB0uni1DB1uni1DB2uni1DB3uni1DB4uni1DB5uni1DB6uni1DB7uni1DB8uni1DB9uni1DBAuni1DBBuni1DBCuni1DBDuni1DBEuni1DBFuni1E02uni1E03uni1E04uni1E05uni1E06uni1E07uni1E08uni1E09uni1E0Auni1E0Buni1E0Cuni1E0Duni1E0Euni1E0Funi1E10uni1E11uni1E12uni1E13uni1E14uni1E15uni1E16uni1E17uni1E18uni1E19uni1E1Auni1E1Buni1E1Cuni1E1Duni1E1Euni1E1Funi1E20uni1E21uni1E22uni1E23uni1E24uni1E25uni1E26uni1E27uni1E28uni1E29uni1E2Auni1E2Buni1E2Cuni1E2Duni1E2Euni1E2Funi1E30uni1E31uni1E32uni1E33uni1E34uni1E35uni1E36uni1E37uni1E38uni1E39uni1E3Auni1E3Buni1E3Cuni1E3Duni1E40uni1E41uni1E42uni1E43uni1E44uni1E45uni1E46uni1E47uni1E48uni1E49uni1E4Auni1E4Buni1E4Cuni1E4Duni1E4Euni1E4Funi1E50uni1E51uni1E52uni1E53uni1E54uni1E55uni1E56uni1E57uni1E58uni1E59uni1E5Auni1E5Buni1E5Cuni1E5Duni1E5Euni1E5Funi1E60uni1E61uni1E62uni1E63uni1E64uni1E65uni1E66uni1E67uni1E68uni1E69uni1E6Auni1E6Buni1E6Cuni1E6Duni1E6Euni1E6Funi1E70uni1E71uni1E72uni1E73uni1E74uni1E75uni1E76uni1E77uni1E78uni1E79uni1E7Auni1E7Buni1E7Cuni1E7Duni1E7Euni1E7Funi1E86uni1E87uni1E88uni1E89uni1E8Auni1E8Buni1E8Cuni1E8Duni1E8Euni1E8Funi1E90uni1E91uni1E92uni1E93uni1E94uni1E95uni1E96uni1E97uni1E98uni1E99uni1E9Auni1E9Buni1F00uni1F01uni1F02uni1F03uni1F04uni1F05uni1F06uni1F07uni1F08uni1F09uni1F0Auni1F0Buni1F0Cuni1F0Duni1F0Euni1F0Funi1F10uni1F11uni1F12uni1F13uni1F14uni1F15uni1F18uni1F19uni1F1Auni1F1Buni1F1Cuni1F1Duni1F20uni1F21uni1F22uni1F23uni1F24uni1F25uni1F26uni1F27uni1F28uni1F29uni1F2Auni1F2Buni1F2Cuni1F2Duni1F2Euni1F2Funi1F30uni1F31uni1F32uni1F33uni1F34uni1F35uni1F36uni1F37uni1F38uni1F39uni1F3Auni1F3Buni1F3Cuni1F3Duni1F3Euni1F3Funi1F40uni1F41uni1F42uni1F43uni1F44uni1F45uni1F48uni1F49uni1F4Auni1F4Buni1F4Cuni1F4Duni1F50uni1F51uni1F52uni1F53uni1F54uni1F55uni1F56uni1F57uni1F59uni1F5Buni1F5Duni1F5Funi1F60uni1F61uni1F62uni1F63uni1F64uni1F65uni1F66uni1F67uni1F68uni1F69uni1F6Auni1F6Buni1F6Cuni1F6Duni1F6Euni1F6Funi1F70uni1F71uni1F72uni1F73uni1F74uni1F75uni1F76uni1F77uni1F78uni1F79uni1F7Auni1F7Buni1F7Cuni1F7Duni1F80uni1F81uni1F82uni1F83uni1F84uni1F85uni1F86uni1F87uni1F88uni1F89uni1F8Auni1F8Buni1F8Cuni1F8Duni1F8Euni1F8Funi1F90uni1F91uni1F92uni1F93uni1F94uni1F95uni1F96uni1F97uni1F98uni1F99uni1F9Auni1F9Buni1F9Cuni1F9Duni1F9Euni1F9Funi1FA0uni1FA1uni1FA2uni1FA3uni1FA4uni1FA5uni1FA6uni1FA7uni1FA8uni1FA9uni1FAAuni1FABuni1FACuni1FADuni1FAEuni1FAFuni1FB0uni1FB1uni1FB2uni1FB3uni1FB4uni1FB6uni1FB7uni1FB8uni1FB9uni1FBAuni1FBBuni1FBCuni1FBDuni1FBEuni1FBFuni1FC0uni1FC1uni1FC2uni1FC3uni1FC4uni1FC6uni1FC7uni1FC8uni1FC9uni1FCAuni1FCBuni1FCCuni1FCDuni1FCEuni1FCFuni1FD0uni1FD1uni1FD2uni1FD3uni1FD6uni1FD7uni1FD8uni1FD9uni1FDAuni1FDBuni1FDDuni1FDEuni1FDFuni1FE0uni1FE1uni1FE2uni1FE3uni1FE4uni1FE5uni1FE6uni1FE7uni1FE8uni1FE9uni1FEAuni1FEBuni1FECuni1FEDuni1FEEuni1FEFuni1FF2uni1FF3uni1FF4uni1FF6uni1FF7uni1FF8uni1FF9uni1FFAuni1FFBuni1FFCuni1FFDuni1FFEuni200Cuni200Duni200Euni200Funi2012uni2016uni201Funi202Auni202Buni202Cuni202Duni202Euni202Funi2034uni203Euni205Euni206Auni206Buni206Cuni206Duni206Euni206Funi2070uni2076uni2079uni2090uni2091uni2092uni2093uni2094uni20A0uni20A1uni20A2uni20A5uni20A6uni20A8uni20A9uni20ADuni20AEuni20AFuni20B0uni20B1uni20B2uni20B3uni20B4uni20B5uni20B9uni20F0uni2117uni214Duni214Euni2153uni2154uni2184uni2C60uni2C61uni2C62uni2C63uni2C64uni2C65uni2C66uni2C67uni2C68uni2C69uni2C6Auni2C6Buni2C6Cuni2C6Duni2C71uni2C72uni2C73uni2C74uni2C75uni2C76uni2C77uni2E17uniA717uniA718uniA719uniA71AuniA71BuniA71CuniA71DuniA71EuniA71FuniA720uniA721uniA788uniA789uniA78AuniA78BuniA78C dieresisacute dieresisgraveuniFE20uniFE21uniFE22uniFE23uni03B1030403130300uni03B1030403130301uni03B1030403140300uni03B1030403140301uni03B1030603130300uni03B1030603130301uni03B1030603140300uni03B1030603140301uni03B9030403130300uni03B9030403130301uni03B9030403140300uni03B9030403140301uni03B9030603130300uni03B9030603130301uni03B9030603140300uni03B9030603140301uni03C5030403130300uni03C5030403130301uni03C5030403140300uni03C5030403140301uni03C5030603130300uni03C5030603130301uni03C5030603140300uni03C5030603140301uni03B9030803040300uni03B9030803040301uni03B9030803060300uni03B9030803060301uni03C5030803040300uni03C5030803040301uni03C5030803060300uni03C5030803060301Eng.alt1Eng.alt2Eng.alt3 uni1FCD02C9 uni1FCE02C9 uni1FDD02C9 uni1FDE02C9dotacutecarondotmacrondieresis tildedieresis tildeacute macrongrave macronacute dieresiscarondieresismacron tildemacron dotmacron dotmacron.capuni030103060308uni030003060308uni030103040308uni030003040308 uni1FDE0306 uni1FDD0306 uni1FCE0306 uni1FCD0306uni0514uni0515uni0516uni0517uni0518uni0519uni051Euni051Funi0520uni0521uni0522uni0523uni0524uni0525uni0526uni0527cyrillic_otmarkuni20BAuni1EFAuni2C6Euni1E9ETurnedauni1EFCuni1EFEuniA722uniA724uniA726uniA728uniA72AuniA72CuniA72EuniA732uniA734uniA736uniA738uniA73AuniA73CuniA73EuniA740uniA742uniA744uniA746uniA748uniA74AuniA74CuniA74EuniA750uniA752uniA754uniA756uniA758uniA75AuniA75CuniA75EuniA760uniA764uniA766uniA768uniA76AuniA76CuniA76EuniA779uniA77BuniA77DuniA77EuniA780uniA782uniA784uniA786uniA78DuniA790uniA792uniA7A0uniA7A2uniA7A4uniA7A6uniA7A8uniA7AAuniA7ABuniA7ACuniA7ADuniA7B0uniA7B1uniA7B2uniA7B3uniA7B4uniA7B6Aogonek.loclNAVEogonek.loclNAVIogonek.loclNAVUogonek.loclNAVLcommaaccent.loclMAHNcommaaccent.loclMAHTurnedeafii10103dotlessafii10105dotless deltalatinuni2C78uni025Cuni025Duni01DDuni025Aiogonekdotlessuni0237uni1EFBuni1E9Cuni1E9Duni2C7A subscriptjuni2C79uni0249dotlessuni029Ddotlessuni02B2dotlessuni03F3dotlessuni1D62dotlessuni1D96dotlessuni1DA4dotlessuni1DA8dotlessuni1E2Ddotlessuni1ECBdotlessuniA723uniA725uniA727uniA729uniA72BuniA72DuniA72FuniA730uniA731uniA733uniA735uniA737uniA739uniA73BuniA73DuniA73FuniA741uniA743uniA745uniA747uniA749uniA74BuniA74DuniA74FuniA751uniA753uniA755uniA757uniA759uniA75BuniA75DuniA75FuniA761uniA765uniA767uniA769uniA76BuniA76DuniA76FuniA771uniA772uniA773uniA774uniA775uniA776uniA777uniA778uniA77AuniA77CuniA77FuniA781uniA783uniA785uniA787uniA78EuniA791uniA793uniA7A1uniA7A3uniA7A5uniA7A7uniA7A9uniA7B5uniA7B7uniA7FAuni1EFDuni1EFFaogonek.loclNAVeogonek.loclNAVlcommaaccent.loclMAHncommaaccent.loclMAHiogonek.loclNAVuogonek.loclNAVf_ff_f_if_f_lf_if_llongs_ts_ta.sc aacute.sc abreve.scacircumflex.sc adieresis.sc agrave.sc amacron.sc aogonek.scaring.sc aringacute.sc atilde.scae.sc aeacute.scb.scc.sc cacute.sc ccaron.sc ccedilla.scccircumflex.sccdot.scd.sceth.sc dcaron.sc dcroat.sce.sc eacute.sc ebreve.sc ecaron.scecircumflex.sc edieresis.sc edotaccent.sc egrave.sc emacron.sc eogonek.scf.scg.sc gbreve.scgcircumflex.scgcommaaccent.scgdot.sch.schbar.schcircumflex.sci.sc iacute.sc ibreve.scicircumflex.sc idieresis.sc idotaccent.sc igrave.scij.sc imacron.sc iogonek.sc itilde.scj.scjcircumflex.sck.sckcommaaccent.scl.sc lacute.sc lcaron.sclcommaaccent.scldot.sc lslash.scm.scn.sc nacute.sc ncaron.scncommaaccent.sceng.sc ntilde.sco.sc oacute.sc obreve.scocircumflex.sc odieresis.sc ograve.scohungarumlaut.sc omacron.sc oslash.scoslashacute.sc otilde.scoe.scp.scthorn.scq.scr.sc racute.sc rcaron.scrcommaaccent.scs.sc sacute.sc scaron.sc scedilla.scscircumflex.scscommaaccent.sc germandbls.sct.sctbar.sc tcaron.sc tcedilla.sctcommaaccent.scu.sc uacute.sc ubreve.scucircumflex.sc udieresis.sc ugrave.scuhungarumlaut.sc umacron.sc uogonek.scuring.sc utilde.scv.scw.sc wacute.scwcircumflex.sc wdieresis.sc wgrave.scx.scy.sc yacute.scycircumflex.sc ydieresis.sc ygrave.scz.sc zacute.sc zcaron.sc zdotaccent.scuni2071uniA78FuniA7F7uniA7FBuniA7FCuniA7FDuniA7FEuniA7FFuni0528uni052Auni052Cuni052EuniA640uniA642uniA644uniA646uniA648uniA64AuniA64CuniA64EuniA650uniA652uniA654uniA656uniA658uniA65AuniA65CuniA65EuniA660uniA662uniA664uniA666uniA668uniA66AuniA66CuniA680uniA682uniA684uniA686uniA688uniA68AuniA68CuniA68EuniA690uniA692uniA694uniA696uniA698uniA69Auni0529uni052Buni052Duni052Funi1C80uni1C81uni1C82uni1C83uni1C84uni1C85uni1C86uni1C87uni1C88uniA641uniA643uniA645uniA647uniA649uniA64BuniA64DuniA64FuniA651uniA653uniA655uniA657uniA659uniA65BuniA65DuniA65FuniA661uniA663uniA665uniA667uniA669uniA66BuniA66DuniA681uniA683uniA685uniA687uniA689uniA68BuniA68DuniA68FuniA691uniA693uniA695uniA697uniA699uniA69Bafii10066.loclSRBafii10068.loclSRBafii10069.loclSRBafii10081.loclSRBafii10084.loclSRBafii10090.loclSRBuniA66EuniA67FuniA69CuniA69Duni2126uni0370uni0372uni0376uni03CFuni037Funi0371uni0373uni0377 uni03D0.altCfrakturHfrakturIfrakturRfrakturZfrakturuniA762uniA763uni212Cuni210Buni2110uni2112PiDoubleStruckuni211BTurnedFuni212B CDoubleStruck HDoubleStruck NDoubleStruck PDoubleStruck QDoubleStruck RDoubleStruck ZDoubleStruckItalicDDoubleStruckGammaDoubleStruckuni2107uni212Auni2130uni2131uni2133uniA796uniA798uniA79AuniA79CuniA79EItalicdDoubleStruckItaliceDoubleStruckItaliciDoubleStruckItalicjDoubleStruckgammaDoubleStruckpiDoubleStruckuni210Euni210FscriptescriptoscriptguniA794uniA795uniA797uniA799uniA79BuniA79DuniA79FuniAB30uniAB31uniAB32uniAB33uniAB34uniAB35uniAB36uniAB37uniAB38uniAB39uniAB3AuniAB3BuniAB3CuniAB3DuniAB3EuniAB3FuniAB40uniAB41uniAB42uniAB43uniAB44uniAB45uniAB46uniAB47uniAB48uniAB49uniAB4AuniAB4BuniAB4CuniAB4DuniAB4EuniAB4FuniAB50uniAB51uniAB52uniAB53uniAB54uniAB55uniAB56uniAB57uniAB58uniAB59uniAB5AuniAB64uni2095uni2096uni2097uni2098uni2099uni209Auni209Buni209CuniA770uniA7F8uniA7F9uniAB5CuniAB5DuniAB5EuniAB5Funi2E2Fzero.lfone.lftwo.lfthree.lffour.lffive.lfsix.lfseven.lfeight.lfnine.lfzero.osfone.osftwo.osf three.osffour.osffive.osfsix.osf seven.osf eight.osfnine.osf zero.slash zero.tosfone.tosftwo.tosf three.tosf four.tosf five.tosfsix.tosf seven.tosf eight.tosf nine.tosf zero.dnomone.dnomtwo.dnom three.dnom four.dnom five.dnomsix.dnom seven.dnom eight.dnom nine.dnom zero.numrone.numrtwo.numr three.numr four.numr five.numrsix.numr seven.numr eight.numr nine.numruni215Funi2189uni2155uni2156uni2157uni2158uni2159uni215Auni2150uni2151uni2152uni2080uni2081uni2082uni2083uni2084uni2085uni2086uni2087uni2088uni2089uni2042uni204Cuni204Duni2045uni2046caretuni2041uni2040uni2050uni2E36uni2E37uni205Cuni2E13uni2E16uni2E08downwardsancorauni2E0Euni2049uni2E2Duni2059uni2055uni2E10uni205Buni2058uni2027uni2043uni2E12uni2E18uni2054uni2E04uni2E1Cuni2E0Cuni2E02uni2E09uni2E20uni204Eonedotenleaderonedotovertwodotspunctuationuni2E19uni2E0Funi2047uni2048uni2E34uni2E33uni2E07uni2E06uni2E0Buni203Buni2E11reversedparagraphreversedquestionmarkuni204Funi2E01uni2E00uni2E05uni2E1Duni2E0Duni2E03uni2E0Auni2E21uni2E30squaredfourdotpunctuationuni2053uni2056uni2E1Euni2E1Funi2E1Buni204Auni2E39uni205Duni2E32uni2E38uni2E35uni2051twodotenleaderuni205Atwodotsoveronedotpunctuationuni203Funi2023uni2E3Cuni2E3Duni2E3Euni2E3Funi2E41uniA673 upwardsancorauni2E31uni208Duni208Ebrackhalfbottomleftbrackhalfbottomrightbrackhalftopleftbrackhalftoprightleftdoubleparenthesisrightdoubleparenthesisuni2E26uni2E27uni207Duni207Euni2E1Auni2010uni2011uni2E3Buni2E3Auni2E40uni2036uni2035uni2057uni2037uni2E42 braceleft.sc braceright.scbracketleft.scbracketright.sc exclam.sc exclamdbl.sc exclamdown.sc parenleft.sc parenright.sc question.scquestiondown.scuniA92EuniA67Euni205Funi2028uni2029uni2061uni2064uni2063uni2062uni2066uni2067uni2068uni2069uni2060uni20B6uni20BCuni20BDuni20AAuni20B7uni20B8uni20BBuni20BEuni2127uni2135uni214Buni2136uni2052uni2138uni208Cuni207Cuni2137uni208Buni207Buni00B5uni2031uni208Auni207AreversedSansSerifLsummationDoubleStruckturnedSansSerifGturnedSansSerifLturnedSansSerifYRotatedQuni2100uni2101uni2106uni2103uni2104uni213Buni2109uni2139uni203Duni2114uni2125uni214C prescriptionuni214Auni211Funi2108uni2120symbolforsamaritansourceuni2121uni2123 weierstrassuni02DEuni02E5_uni02E5_uni02E9uni02E5_uni02E5_uni02E6uni02E5_uni02E5_uni02E8uni02E5_uni02E5_uni02E7uni02E5_uni02E9uni02E5_uni02E9_uni02E5uni02E5_uni02E9_uni02E9uni02E5_uni02E9_uni02E6uni02E5_uni02E9_uni02E8uni02E5_uni02E9_uni02E7uni02E5_uni02E6uni02E5_uni02E6_uni02E5uni02E5_uni02E6_uni02E9uni02E5_uni02E6_uni02E6uni02E5_uni02E6_uni02E8uni02E5_uni02E6_uni02E7uni02E5_uni02E8uni02E5_uni02E8_uni02E5uni02E5_uni02E8_uni02E9uni02E5_uni02E8_uni02E6uni02E5_uni02E8_uni02E8uni02E5_uni02E8_uni02E7uni02E5_uni02E7uni02E5_uni02E7_uni02E5uni02E5_uni02E7_uni02E9uni02E5_uni02E7_uni02E6uni02E5_uni02E7_uni02E8uni02E5_uni02E7_uni02E7uni02E9_uni02E5uni02E9_uni02E5_uni02E5uni02E9_uni02E5_uni02E9uni02E9_uni02E5_uni02E6uni02E9_uni02E5_uni02E8uni02E9_uni02E5_uni02E7uni02E9_uni02E9_uni02E5uni02E9_uni02E9_uni02E6uni02E9_uni02E9_uni02E8uni02E9_uni02E9_uni02E7uni02E9_uni02E6uni02E9_uni02E6_uni02E5uni02E9_uni02E6_uni02E9uni02E9_uni02E6_uni02E6uni02E9_uni02E6_uni02E8uni02E9_uni02E6_uni02E7uni02E9_uni02E8uni02E9_uni02E8_uni02E5uni02E9_uni02E8_uni02E9uni02E9_uni02E8_uni02E6uni02E9_uni02E8_uni02E8uni02E9_uni02E8_uni02E7uni02E9_uni02E7uni02E9_uni02E7_uni02E5uni02E9_uni02E7_uni02E9uni02E9_uni02E7_uni02E6uni02E9_uni02E7_uni02E8uni02E9_uni02E7_uni02E7uni02E6_uni02E5uni02E6_uni02E5_uni02E5uni02E6_uni02E5_uni02E9uni02E6_uni02E5_uni02E6uni02E6_uni02E5_uni02E8uni02E6_uni02E5_uni02E7uni02E6_uni02E9uni02E6_uni02E9_uni02E5uni02E6_uni02E9_uni02E9uni02E6_uni02E9_uni02E6uni02E6_uni02E9_uni02E8uni02E6_uni02E9_uni02E7uni02E6_uni02E6_uni02E5uni02E6_uni02E6_uni02E9uni02E6_uni02E6_uni02E8uni02E6_uni02E6_uni02E7uni02E6_uni02E8uni02E6_uni02E8_uni02E5uni02E6_uni02E8_uni02E9uni02E6_uni02E8_uni02E6uni02E6_uni02E8_uni02E8uni02E6_uni02E8_uni02E7uni02E6_uni02E7uni02E6_uni02E7_uni02E5uni02E6_uni02E7_uni02E9uni02E6_uni02E7_uni02E6uni02E6_uni02E7_uni02E8uni02E6_uni02E7_uni02E7uni02E8_uni02E5uni02E8_uni02E5_uni02E5uni02E8_uni02E5_uni02E9uni02E8_uni02E5_uni02E6uni02E8_uni02E5_uni02E8uni02E8_uni02E5_uni02E7uni02E8_uni02E9uni02E8_uni02E9_uni02E5uni02E8_uni02E9_uni02E9uni02E8_uni02E9_uni02E6uni02E8_uni02E9_uni02E8uni02E8_uni02E9_uni02E7uni02E8_uni02E6uni02E8_uni02E6_uni02E5uni02E8_uni02E6_uni02E9uni02E8_uni02E6_uni02E6uni02E8_uni02E6_uni02E8uni02E8_uni02E6_uni02E7uni02E8_uni02E8_uni02E5uni02E8_uni02E8_uni02E9uni02E8_uni02E8_uni02E6uni02E8_uni02E8_uni02E7uni02E8_uni02E7uni02E8_uni02E7_uni02E5uni02E8_uni02E7_uni02E9uni02E8_uni02E7_uni02E6uni02E8_uni02E7_uni02E8uni02E8_uni02E7_uni02E7uni02E7_uni02E5uni02E7_uni02E5_uni02E5uni02E7_uni02E5_uni02E9uni02E7_uni02E5_uni02E6uni02E7_uni02E5_uni02E8uni02E7_uni02E5_uni02E7uni02E7_uni02E9uni02E7_uni02E9_uni02E5uni02E7_uni02E9_uni02E9uni02E7_uni02E9_uni02E6uni02E7_uni02E9_uni02E8uni02E7_uni02E9_uni02E7uni02E7_uni02E6uni02E7_uni02E6_uni02E5uni02E7_uni02E6_uni02E9uni02E7_uni02E6_uni02E6uni02E7_uni02E6_uni02E8uni02E7_uni02E6_uni02E7uni02E7_uni02E8uni02E7_uni02E8_uni02E5uni02E7_uni02E8_uni02E9uni02E7_uni02E8_uni02E6uni02E7_uni02E8_uni02E8uni02E7_uni02E8_uni02E7uni02E7_uni02E7_uni02E5uni02E7_uni02E7_uni02E9uni02E7_uni02E7_uni02E6uni02E7_uni02E7_uni02E8uniAB5B ampersand.scuni2129uni0308uni0307 gravecomb acutecombuni030Buni0302uni030Cuni0306uni030A tildecombuni0304 overlinecmbuni030Duni030Euni030Funi0310uni0311uni0312uni0313uni0314uni0315uni0316uni0317uni0318uni0319uni031Auni031Buni031Cuni031Duni031Euni031Funi0320hookpalatalizedbelowcombhookretroflexbelowcomb dotbelowcombuni0324uni0325uni0326uni0327uni0328uni0329uni032Auni032Buni032Cuni032Duni032Euni032Funi0330uni0331uni0332uni0333uni0334strokeshortoverlaycombstrokelongoverlaycombslashshortoverlaycombslashlongoverlaycombuni0339uni033Auni033Buni033Cuni033Duni033Euni033Funi0340uni0341uni0346uni0347uni0348uni0349uni034Auni034Buni034Cuni034Duni034Euni034Funi0350uni0351uni0352uni0353uni0354uni0355uni0356uni0357uni0358uni0359uni035Auni035Buni035Cuni035Duni035Euni035Funi0360uni0361uni0362acutegraveacute acutemacronuni1DFEuni1DFF brevemacroncombiningconjoiningmacroncombiningmacronlefthalfcombiningmacronrighthalf dottedacute dottedgravedoublecircumflexabovegraveacutegrave gravemacronuni1DD0uni1DC4 macronbreveuni1DC6 ogonekabove snakebelowsuspensionmarkuni1AB0uni1AB1uni1AB2uni1AB3uni1AB4uni1AB5uni1AB6uni1AB7uni1AB8uni1AB9uni1ABAuni1ABBuni1ABCuni1ABDuni1DE7uni1DE8uni1DE9uni1DEAuni1DEBuni1DECuni1DEDuni1DEEuni1DEFuni1DF0uni1DF1uni1DF2uni1DF3uni1DF4uni1DF5uni1DFBuni1DFCuni1DFDuni2DE0uni2DE1uni2DE2uni2DE3uni2DE4uni2DE5uni2DE6uni2DE7uni2DE8uni2DE9uni2DEAuni2DEBuni2DECuni2DEDuni2DEEuni2DEFuni2DF0uni2DF1uni2DF2uni2DF3uni2DF4uni2DF5uni2DF6uni2DF7uni2DF8uni2DF9uni2DFAuni2DFBuni2DFCuni2DFDuni2DFEuni2DFFuniFE00uniFE27uniFE28uniFE29uniFE2AuniFE2BuniFE2CuniFE2Duraboveusabove zigzagbelowuni1ABEdieresiscomb.scdotaccentcomb.sc gravecomb.sc acutecomb.schungarumlautcomb.sccircumflexcomb.sc caroncomb.sc brevecomb.sc ringcomb.sc tildecomb.sc macroncomb.sc ogonekcomb.sc overscore.scuni0342uni0343uni0344uni0345uni0483uni0484uni0485uni0486uni0487uniA66FuniA674uniA675uniA676uniA677uniA678uniA679uniA67AuniA67BuniA67CuniA67DuniA69EuniA69FuniFE2EuniFE2FuniA670uniA671uniA672uni1DDBuni1DDEuni1DDFuni1DE1uni1DE2uni0363uni1DD4uni1DD5uni1DD6uni1DD7uni0368uni0369uni0364uni1DD9flattenedopenaaboveuni1DDAuni036Auni0365uni1DD8uni1DDCuni1DDDuni1DE5uni036Buni1DE0uni0366uni1DCAuni036Cuni1DE3uni1DE4uni036Duni0367uni036Euni036Funi1DE6uni2C7Duni2C70uni2C7Euni2C7FuniA7AEuniAB60uniAB61uniAB62uniAB63uniAB65ogonekcenteringsummationDoubleStruck.miruni20BFuni2E43uni2E44uniA700uniA701uniA702uniA703uniA704uniA705uniA706uniA707uniA708uniA709uniA70AuniA70BuniA70CuniA70DuniA70EuniA70FuniA710uniA711uniA712uniA713uniA714uniA715uniA716YYII-"-YYII-!-\\LL;-D-EE>>h-h-EE>>--YYII-"-::,,+~a-4wa-::,,a-g-, UXEY KQKSZX4(Y`f UX%acc#b!!YC#DC`B-, `f-, d P&Z( CEcEEX!%YR[X!#!X PPX!@Y 8PX!8YY  CEcEad(PX! CEcE 0PX!0Y PX f a PX` PX! ` 6PX!6``YYY% CcRXK PX! CKPX!Kac CcbYYdaY+YY#PXeYY-, E %ad CPX#B#B!!Y`-,#!#! dbB #BEX CEc C`Ec*! C +0%&QX`PaRYX#Y!Y @SX+!@Y#PXeY-,C+C`B-,#B# #Babfc`*-, E Ccb PX@`Yfc`D`-, CEB*!C`B- ,C#DC`B- , E +#C%` E#a d PX!0PX @YY#PXeY%#aDD`- , E +#C%` E#a d$PX@Y#PXeY%#aDD`- , #B EX!#!Y*!- ,EdaD-,` CJPX #BYCJRX #BY-, bfc c#aC` ` #B#-,KTXdDY$ e#x-,KQXKSXdDY!Y$e#x-,CUXCaB+YC%B %B%B# %PXC`%B #a*!#a #a*!C`%B%a*!Y CGCG`b PX@`Yfc Ccb PX@`Yfc`#DC>C`B-,ETX#B E #B #`B `aBB`++"Y-,+-,+-,+-,+-,+-,+-,+-,+-,+-, +-),# bfc`KTX# .]!!Y-*,# bfc`KTX# .q!!Y-+,# bfc&`KTX# .r!!Y-, +ETX#B E #B #`B `aBB`++"Y-,+- ,+-!,+-",+-#,+-$,+-%,+-&,+-',+-(, +-,, <`--, `` C#`C%a`,*!-.,-+-*-/, G Ccb PX@`Yfc`#a8# UX G Ccb PX@`Yfc`#a8!Y-0,ETX EB/*EX0Y"Y-1, +ETX EB/*EX0Y"Y-2, 5`-3, EBEcb PX@`Yfc+ Ccb PX@`Yfc+D>#82*!-4, < G Ccb PX@`Yfc`Ca8-5,.<-6, < G Ccb PX@`Yfc`CaCc8-7,% . G#B%IG#G#a Xb!Y#B6*-8,#B%%G#G#a B C+e.# <8-9,#B%% .G#G#a #B B C+ `PX @QX  &YBB# C #G#G#a#F`Cb PX@`Yfc` + a C`d#CadPXCaC`Y%b PX@`Yfca# &#Fa8#CF%CG#G#a` Cb PX@`Yfc`# +#C`+%a%b PX@`Yfc&a %`d#%`dPX!#!Y# &#Fa8Y-:,#B & .G#G#a#<8-;,#B #B F#G+#a8-<,#B%%G#G#aTX. <#!%%G#G#a %%G#G#a%%I%acc# Xb!Ycb PX@`Yfc`#.# <8#!Y-=,#B C .G#G#a ` `fb PX@`Yfc# <8->,# .F%FCXPRYX +-o,:+?+-p,:+@+-q,:+>+-r,:+?+-s,:+@+-t,;+..+-u,;+>+-v,;+?+-w,;+@+-x,;+>+-y,;+?+-z,;+@+-{,<+..+-|,<+>+-},<+?+-~,<+@+-,<+>+-,<+?+-,<+@+-,=+..+-,=+>+-,=+?+-,=+@+-,=+>+-,=+?+-,=+@+-, EX!#!YB+e$PxEX0Y-KRXYcpB@ z\@,*B@mcSG3!*B@wh[M=**BA %   *BA @@@@@@@@ *D$QX@XdD(QXXDY'QX@cTXDYYYYY@oeUI5# *DdDD ttfautohint version = 1.7 adjust-subglyphs = 0 default-script = latn dw-cleartype-strong-stem-width = 0 fallback-scaling = 0 fallback-script = none fallback-stem-width = 0 gdi-cleartype-strong-stem-width = 1 gray-strong-stem-width = 0 hinting-limit = 200 hinting-range-max = 50 hinting-range-min = 8 hint-composites = 0 ignore-restrictions = 0 increase-x-height = 14 reference = reference-index = 0 symbol = 0 TTFA-info = 1 windows-compatibility = 1 x-height-snapping-exceptions = control-instructions = linphone-desktop-4.2.5/linphone-app/assets/fonts/NotoSans-hinted/NotoSans-Regular.ttf000066400000000000000000015710241376717241300307560ustar00rootroot00000000000000 GDEF,GPOS(GSUBD7jOS/2lU`TTFAQcmapŸ .cvt ~50tfpgm:(| mgasp(glyfr0Lhead`6hhea ($hmtx-3V2loca3X2maxpQ name義Q4\postWprep6`Z$=D]IUUW  ((==@@BEGJLinquU`V\\cdfikptt&@DHH\q   <FGLOQRTUXY\\^_dgiit{}        * 1 3 3 = K N O V V \ _ c c e e o o r r t x z ~                                        ) , - / 1 2 2 : < > ? @ A B F G G H H K S U U V V W \ ` ` c c f s t t u    $,44BBJS ;w-# ((    # % ) + , - . / 0 1 7  =  &E ( )\ , -^ / 1` 3 9c < <j I Ik N Nl U \m ` `u f mv o s~ u w y    = m q v z ~ ST  %&VV   , 2 5 8 9 : < > A J N T V  1f : ; > H K M O b f ,         ! ' ( ) X k m o p q r u v w y z | } ~   4nDFLTcyrlgreklatnkernmarkmkmk. o2̾\l4׆B V   |ff h 4Ff rt*0f 4 Bffff ^ Xf h h h ^ h h r r rF"` | h F  F4 " h" `" X  $ r   *0`F"\\br6vzv""FFFFFF""""````````""""4FF``fffffffffffp.^ ^^^l.....<FdZ $%&'()*./2345679:;<=>FYZ\^cm} #%'56789:<>BDFUZ[\^_`aceghklnopqrstuwx}    ?@DGISTVWXY`dfpuxy{}~   !#)+-/13579;=?EGIKMOPQRST`>?@ABCDEFGHIJKLM !"#         79:<#%'579OQS`. "$@`B D         m        -ZM(-279:<#%'579OQS`-d79:<#%'579OQS` ;-nPP-2"PF m]elrlmnopq]  l m n o p q        m]lmnopqru ?^achopqsw @r]^aehl lmnopqm]x|}>?@ABCDElmnopqz{|}~    x}>?z{ x} >?z{3x} >?@ABCDEz{|}~  V`9 VW^df"paprtp;ops a VWZ& 2 `df  * 2 `df  Qegodf[a*  `df  + 2 Q`defgo  [a[an_aZ Vdf  +  V`dfn-2-<;,;2,;2  0  "" " prtru cscopstp                                      <<<<              )ZZ                9>BFUUY^`aehllnnpqssuxz{}}     @@ CE GJNNPTVZ\\^^apu|/7:FHTXZ\^`dem{}$)ACCET`a>MZ[j{ $6>RUV`b $glmx      ! !<;<$$&&+''((..C//*2233U44774889:';;C<<===DDIIPKKPQUU:WW0YZ [[D\\ mmN}}M+U ++++QCD***Q**      :::##4$$0%%4&&0''4((0))++--//113355'66 7788 99::=<<=>>=BBCCDDFFUU YY ZZ[[\\]] ^^ ``Waa eeff ggVhh llnnTppWqqssVuuvv wwxxzz{{}}OOX &%1&32%2 S1%&& B$$R$R%' ' '  ;!<  !  <NM  @@CCDDEEGG)HH"II(JJ NNPP QQ8RRKSS$TT1VV3WWJXX3YYJZZI\\I^^2aabb ccddee8ffgg8hijj kkll mmnn oo8pp1uuvvwwKxx$yySzz{{>||H7/27/>1%GFGF7/EE3B3B  2    %>H7//6.6.6.6..          !!##))++--//11335577)88"99)::";;)<<"==)>>"??)@@"AACCEE(FF GG(HH II(JJ KK(LL MM(NN OOPP QQRR SSTT ``4aa0>?@EFM Z[jklq ry z{   T !"#$$P#L@?@?99 -  , 5 A A A : : ?,;,$$ &&**224477288 9:"<<===@@?DDEEFHIIJJ*KKNOPQRRSSTTUUVV9WW(XXY\]]5``?mmL}}K Q    ****    9  9##2$$(%%2&&(''2((()) **++ ,,-- ..// 0011 2233 4455"66778899::=;;5<<===5>>=??5BB CCDDQEEFFGGII9]]^^3aa3eePhh3llPqq#ww#xx yy+zz{{)||}} M+)M I> I  01!N0 ! /  . -/ < <.""";:,  :  ,,LK@@#CCDD EEGGHHII JJNN OOPPQQ7RR'UUVV1WWYY]]^^!`` bbcc ddHee7ffHgg7hhii jjkk llmm nnoo7ppqq vvww'xx<zz{{'~~!/'<  NGFGF - -EDED -111 CC!/   !/0.0.0. -'B B A@A@                       ""$$))**++,,--..//00112233445566778899::;;<<==>>??@@AA BBCC DDEE FFGG HHII JJKK LLMM NNOOPPQQRRSSTT``2aa(#>? @E NO+PS&Z[\ajk)lqz{ |6 &+)      3 >#OJ88 %  $ 4g hne$=D]4KIjUUW  ==BEGJLinquU`'V(\\gcdhgijkpmttst $@DHH\q BRXY]`ef  g ikn<pFGLOQRUUXY\\^_dgiit{}   :  >  B * /C 1 1I > KJ N OX V VZ \ _[ c c_ t x` z ~e j l n o q r s t u v w z {             ^0NJH_JP^8KJ_n^b._n^_8TP.^^^^^^8_J_J_J_J_JTKP_n_n_n_n8888P._n_n_n_n_nP_8_8_8_8PP^^28._n_n_n8_nNNN>.888DJbPV\b.hn.tf(_J_n_J_n_J_nz_^^^^_8_8_8_8_8 TKPKJ.J.J.JTP^J*^24J_J^H^_J0P^KN8NTK.(Z.(b_n.Z,XTZ_nZT2.^22N`_8KK.BH_J0P^N8l.~_nf_\G_nPZ J_n(8b*.PjTTTKPTbHT_nD8K_nj"@(.4:8@FLRNXTP@D@D^djpv|ZJZ ..*DKKlPl K`f$*06<*BHNTZ^^_nD,D,`f_8_\KK_J_nTPTPPPPlZrx~82J*l.^^^^^^^^^ _n_n_n_n_n_n 8_J_n_J_n_J_n_J_n_J_n_J2_J2_J2_J2_8 &PKPKP.,2822@28l22>"D_8J\PV\bhn(Ttz TK_\  ^8_J_n_8_8_8_8_8^^N N.^^_n_n88_J_n_J_n_8_8"(.4:@F^$*_J_n_J_n_J_n_J_nKPLGRX^^^djpKP222j2,,.v|.(^(((PT_8PZ_J $*06t<BHNTZ`flrx~ZJbTP~TJ.PPP_?.._\dd> &,28>DJJPV\bhn""tz":^@vj .^(P^"(.4v:@ FLLvvRXX^^djpv| _n_n$*0^N6<BHNTZ`8flrx ~ ~H._J_n_J_n_J_n_J_nPP^^_8_8_8_8 &T,288KPJ.>DJ.^TPJ^^V\lbb......hhntzz((((((((_n_n_n_n_n_nZZZZZZZZTTTTTTTT "(..((_n_nZZTT44L:@FLL((((((((RX^djpv|^^^^(((((~ZZZZZZKKT  22P$*06<BHKD^N TZZZZZZZZZZZZ`f_lrx~.K_J_JPK=_8aJ^ 8b_\&,28>bDJJPV\bbtbhn tz...J "...(..4444:@LLLFL^^^^^^^R^X^ddjp|||v| 92$*06<NBH_J_JNTZ`flFrx~@G@K^_8^ &&,28>DJPV\bhntzK==D$,$#2BVJ# #,##|#5#{H#~###l$##8==nDsDZ8F\9GDR Ir&*>}b$BDJGF DG$ODF[?G t$DGCm89bcdefghiz{|}~ !BceGQRde . \p? F?n??\??????????\ Fp?np?np?np?n???????\?\?\???????F?? ???????????????\\\ pp?n??????\\ ????F????????pF?V &,28>DJP V\ \ \ \ \ FFFFFp?np?np?np?n?????????\?\?\?\F?\bhntz?????????\Fp??pp?n ?n?n"((..44444:::::::::@@@@?FLRX^djppvee T( vmeeeMeFeVeOee_e'e(eee[eZePeceYeeeseeeAeee > 4 1    #,<5   ATAvAeeG$ Hne$=D]4KIjUUW  ==@@BEGJLinquU`*V+\\jcdkgimkppttvw $@DHH \q "EU[\`chi  j lnq<sFGLOQRUUXY\\^_dgiit{}   =  A  E * /F 1 1L > KM N O[ V V] \ _^ c cb t xc z ~h m o q r t u v w x y z } ~             :~ "n < $$0 #| "::$:l#R$2<h $< I: $B$$ ; $r :Z 5Bl$$J ",,,888HJJJNdtttd$$   TrZ5$<222>>>"`PPPf;zzz l&r Nx~  I,2$B`ZD $>$0 0     z " z " V\JPb$ b :l:Z:l:Ztz#R LRdV\b\b &,2JP :~8>DJ:~ P h: $0 #| ":l:#R:l<:V\bhnt$N .(z#";;N $r8I, $#R:~ # :#v#|:#R ":l<=#$ I#I#: I#; $<$<I##  x# r $"$(.4:#@FLRLRX^dj:>6jp:~ :;#R ,v2|r5#:; 4HN H$r $* :  #p\ "$<:l$,,~I*0$N#^;#^$B6<6< BH #dH#R$NN#^vTZ `flrx~ F<:;  ~&, 28>zDJ4PV "\bh(nt:~ z & I,2  $:;"("(.4:@JPFLFLRX^d$r#R jpv|v|:l:Z  :~ I#p$*h   ":$$ *p#F0:l:#d<<6< :BHNT RZ`flrx~ 8>JPtz$r*0:;z &,28>ZDJPV\bhntzh I#:~ "6 :l #R $$$$r$  $r$rI  F"($H v I,, ..$#4: @FFF L;R<xXxxx^^ dd vdjp ;v,5|I$H$:#4X  2:X$ $< *06<B;HN2TZ`fl;$<$:rx$ "#|8;~ "~:$r25I## ;;;I#   :2$ &,28>>DJPV\bhnn|tz#:jpjjF ^$$  # ; : |"(. p#j#4 p44#4:@FFjjLpRX^djpv| n n n n  I I$B $B$B $$*0$0 $0  6<   BH#| NT " " " Z`flrx~$ $  :l:Z:l:Z:l:Z#R  &,258>DJPV\bhh$BntzXXXXXX^^:~:~5."4TT:**057h 45.4z"7h4(.4:@@FFLLRRXXXXXX^^dd|jpv||$N:~:~ $*06<BHHNTZ`flrx~~4t #j #j$$$B$0 $ &,2 (8>>>>DDDDJJJJPPPPVVVV\\\\bbbbhhhhn "tz#|5:$$0$0$0 ::::$$ " "$0 " : 7:~  #R  " ( v v . 4 : @ F L v v v R X X; ^ d v v p v j v p p v v | $r$r # I $ !!! !!!!$!*!0!"""""!6!B!B!"D"J"P"V"V"\"n"b"h"n""t"z""z""""""""N"""""""""""""""""## ####"#(#.#4#:#@#F#L#R#X#^#d#j#p##v#|::#:###$H##############I#####:~$$$$ $$$$$$*$0$6$<$B:$H$N$T$Z$`$f$l$lI$r$x$x$x$~$$$$$$$$$$$$$$$$$$$$$$%%%%*>|1//>i1W1))2{nW5n51"n@F#7% %F%%4F*4/%4%%158 A,JG\  ]BR> Vr&U}8$JFO[j`wKz>>1\rw&WBB/=8W88]3 % AfHd%>5>,> g>s>L>n>q1511,1 g1s5/5/, /g/s445n55QQ5QQ552|L4 6 W$&pRyn5Dn5g>D>EWW/$R)K>1//77n5n5sP*>/D//EE0 5I<3? 4?n':aaaa'k~3)E<cl== 5d@nY['.aaaaaZa7a|aaadaaaak>aaaahaTa0aaaTvaaaaaaaaBBR|i111*W)sssgTW|5#/q/R//=L=L77WRYn5n5n#5qn5R,,$$""R11* MFO_*Y***'4Hq*01-*O* /477\fPR\FF\ONWM\cFI9D7777>>WFFFxg \W444 /44\Wz k7j7j4j44i5 u8mAc@o.=41|.'TZTTaq>L4)Du5( <"<Uh<^8#"#<"<<A<AA"ACA,""<<v"<vv<<p<88"8<8<<<<<"<>=<<v<<<<"<"<,<<"<+<****"**<*U*<<"<<"<"Tv n]hrbZ9A*|L,@u#aaB<>n&T,7 4Th7d+3a{>4h%PY7/) *.2$=D]4:CINTY_du  &(?HIUUW[^_bgijllnnpqssvw~   BELLNN$&()*+%,'6UADeOTi`aoppqrsv  ((..2255<<FFTTVVY[eekk}}  (*03599;<>> BG IJMSVV\\cciilptt#$%&)*,<ZFMTYbir  !@CHHbceg"%*+  , .02 411:99;FG<MO>QRAUUCXYD\\FdgGt{KSYfno      - . N N z z                    t @ R  ~ , rVD .D  F R X      hV | h  @ R R R RVDDDDD X X X X hVVVVVhhhh    @ @ @ @  R R R R R  ~ ,,,,VhVhVhDVDVDV    F F F F R R Xh Xh Xh Xh Xh Xh F   t R D rVD . R   V V R F ~ t R r D . @ R V |  r  R @   R DV             R R R R R R R R DVDVDVDVDVDVDV Xh Xh R X DV Xh Xh Xh Xh Xh  DVDV Vh  R R DVDV   Xh Xh  R DVDVDVDV  @ , R X R  " " (h D.4 Z: @FLRX ^  @ @D djpv|  * x     $ * 0 6 < B ^ H N T Z `h f |  | l r x ~ Z t t t @  R R R R R   ,,,, r r VhVhVhVhDVDVDVDV . | . |     F F F F F R R R R Xh Xh Xh Xh Xh     n      &  , 2 2 8 VVVVVV \ > D J P V \ b hVV n t z        " R ( ,DD . 4 :DD  V @ V F L  R X,V ^ d j p  v |  hh h hh &&&&&&&&&&                      $ $ $ $ * * * * * * 0 0 0 0 6 6 6 6 6 6 6 6 6 6 6 < B B B B B H N N N N N T T T T Z ` f f l rD x ~        &xm&S 2 \aa>aaKa4;;>@nQDA|\PLaOgbaX?ava|au, =ajJaYa=jkJY<+aia6ma aO6(tXi%5TV;Oxlv`bfg("_\'"HLbvKxuI@dAZaWNIu+- )<<<2<<<<<C<<<<<[<<d<<<<@<<<<<<w(W\hXhh?m|+4VZDy"~ &8J\n|B   Dg 31 $ &b   -"(.47<7}<}$*06<E>E0>q T  f-T 0 = o rB$T6BTf      e ee /  "(.4''71'<17<  \4fT 0 3 = e o r c &8J\bb|(j   >aT1 $ }   /"(.47<7<$*06<=/=D D> P if-T 0 = o r c BT`lx,2@T`r0 ?P<H3  l  2X  ) O * :4&zF |" <<( / ?"(.4Yb]$*06<T TD !G  L((    # % ) + , - . / 0 1 7  8 3 9: < <A I IB N NC  D((    # % ) + , - . / 0 1 7  =  &E ( )Z , -\ / 1^ < <a N Nb U \c ` `k f ml o st u wy y | E..("^(....(..^.LL@^4:@FLRX^djpv||Y3dXX""(.4:@FLRX^djpv| N$*B06<B~HNTZ`flrx~#40*YPQ$&98GFHmf"&O"4%!o% ,l%ll(  ( " "l;l!$ MlVl ll  l llll l l l  2p =   m q v z ~  &,28&"^  V    $ ST  %&VV   , 2 5 8 9 : < > A J N T V  1f : ; > H K M O b f ~ $ %& & ) , - . 0 2 5 6 ; ? E G  L  )V , -n / 1p : ;s > Hu K M O R U \ ` ` f m o w y .L4:@LLFLjRX^djpv|rrrr`rlrflfrr`rrr`r``r```rfrrr6rrrrrrll6frrf``rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrf $*`0H6<BHNTrrrrrrrr``Zr`frrrrrrrrrrrrrrlrrrrrrrrrrrrrrrrrr${~! ."+ j16|=`<!< <<'<&<<%<<?`flx~rx~d &,28h>>DJPV\^bhnttz^ "(.4:@@FLRX^djpv|5$:+\8cM61JLb?\&O# 7FH|C B.pBBBBC;B87)Ab*)7)F   BMBBVBB B B  !BBt B B  l (         ! ' ( ) X k m o p q r u v w y z | } ~  $*i(RX^jdvjpvv|hwhBBCrBBmByBzBp;+BBT^BdBPt|BtBxBbB *DFLTcyrlFgreklatn  SRB 2  "CAT JMAH tMOL NAV ROM       aaltc2sccaseccmpccmpccmpccmpdnomfraclnumlocllocllocllocl loclloclnumronum"ordn(pnum.rtlm4smcp:subs@supsFtnumLzeroR!#      $"%&NbnnT  D D f  6 J $   $ 2 p p P P.B   2 fT ((   & ) , 0 3 7 N N9     ! " # K M$ k k' p r( v w+ | |- ~ ~. / 0&*,+"#<3g456789:;LM(5jN^0:DNj|",6@JT    LG   I 3     LH   J 4 :BJRZbjrz                            :BJRZbjrz + - / . , 6 9 8 7 A C E D B ; = ? > < 1 3 5 4 2 * @ : 0:BJRZbjrz c e g f d o q s r p z | } { u w y x v i k m l j b n t h:BJRZbjrz G I K J H S U W V T ] _ a ` ^ X Z [ Y M O Q P N F R \ L:BJRZbjrz           % ' ) ( &  ! # "        $ ' )  I I I I$(,28DHLRX&( n&0:DNX        $.8BLV`jt~            $.8BLV`jt~            } "#34HI#$ `a  4R<R^(^jjyOy/yy2 - . / 0 1 2 3 4 5 6   KNOPQSVW$ ={tu*+>,-?   Q   "B*    ! $,$D2Rl|l|$2DR .    .       .        :     J          > ? @ A B C D E F G H I "$%&'()*+,-./0123456789:;<=>@^`cq  !#%')+-/13579:<>BDFH` <     J          > ? @ A B C D E F G H I ">@DEFGHIJKLMNOPQRSTUVWXYZ[\]^`cq   "$&(*,.02468;=?CEGIa B      FXKX^2B @)GOOG@--%    ~01ac67Y] %&AEbw~  OP\_'/=?EMWY[]} d q  !_!!,m,-.Ds}!.Ze/ 12bd78Z^ &'BFcz PQ]`(>@ HPY[]_ f t !!!,`,n-.@t~".0[ KMHS {JL@By]><:8654320/.,+)(.Jf2ee`\`eaa^2;?.>D<RfjHhTHI#$)*&'JKLMNOPQR  k r w ~ p q v | v { w | x } y?@AO O P Q R Sstuvwxyz  ?  @  A  B  < : ; t l m n o x s u f y z g h } i j {    DE./$OPQRST-~'()* +,   -   [  O ./0123 4 < f 5 > = 7 P : ; _ ` H z h 8 9 Z j ? u S K v N J M B |6 789:;<= *+>,-?  EFGHIJK U U   W   ! XY * + ,Z[ $ % & ' ( )"#$% " klmnopq%20!1 l k W p T m d c E X q e V o G ^ L g Q C F Dr R ] y U n w x Y r \ t I i s } b a  @ A ~ {  L  M  N  O  P  Q R ! S " T # U $ V % W & X ' Y ( Z ) [ * \ + ] , ^ - _ . ` / a 0 b r T c d e s 1 c 2 d 3 e 4 f 5 g 6 h 7 i 8 j 9 k : l ; m < n = o > p t u _ `=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\] ^_`abc defghijklmnopqr~ s  t u  v wxyz {|  } ~  3 4 5 6 7 8 9 a b^*@'eU]M+3!%!!^563dH@]K_L$# +7#34632#"&9kt$%%$l%%$ AW$@!]L +#!#77lG@D  fe  KL +3##7##7#537#5373373337#)G)'F&~ (H((E(CCBB>")0p@0*$#  !JK-PX@~hL@!W`PY@"" +5&&'55&&546753&&'56654&'7h "j3c\gX@5W$ M(BX-h_@63-|;60A:kURGJTXWJ +?2FW o۱*!(++"&&1 %/KPX@, h g _  K _L@4 h g K _ KK _LY@+'& -+&/'/!%%      +2#"&546#"32542#"&546"3254IMIMGKFtM&##&MhIMIMGKFL&##&Mujjwwjju 64QPPRujjwwjju?PPQQ5+5z@&5JKPX@#_K_K_L@!_K]K_LY@! 31 +!+  +26673#'#"&5467&&546"6654&32670P]Q>! Y0&wW/tShySG 7bS*5&$;30R6=J>@[ QI?X$Q/Am)T*4f^L^($R7ISH,'$=%"<)$. B67B*A@]L +#7(b @L +4673#&&(GLSFGGERLGz[^wt^Xb @L +#6654&'3GLREGGFSLGyX^tw^[)63@  GK)PXLtY@  +7''7'7'BwVUMYu6\//\62oS &@#Ue]M +3##5#5353AHHGG)t@U]M +7#6670At 5694(3@U]M +753(NNHy @_L$" +74632#"&H$&&$6%%$  j@KL +#jV 61  @_K_L$$%# +#"&54663232654&#" 0iUys/hUxv~CQPEEPQCftXítWYc @ JKL +!#467'73cVL.I+4>;0*@' J_K]L'%( +!!57>54&#"'6632!(5K&F85N)/*mDdt.R7iI6TP1;=$ ;#1fX8b`5-*@@=$J%Ig_K_L%$!$%* +#"&'532654&##532654&#"'6632QCUU:y_8`,-h0`Ui_EFX[F<:R(,&qHpm#HU XG?`6RKBC;KJ=49"<,d( 1@.JfKL   +%##5!533#5467#(hUP[h ֢K#4I!,?D@A  Jg]K_L  +2#"&'532654&#"'!!66m~8`!$g/OaV]H,f:ndoSKOFK QP7 ,>@; Jg_K_L &$, ,$'%$ +4>32&&#"36632#"&&2654&#"7Ge3.E\5R@]r{hDnA?NEE/F'"D1MyHK.Ph;#1qhpDQUDP'=+U7, %@"J]KL +3!5!%zPDz1 (56@33#J_K_L-+((  +2#"&54667&&5466"6654&32654&''^x%>%,H+jt{)D'5H8`<8F#<$4GFJMIMRDBEXS+@14F1Zie[0I4UB6L(G52%2#>625(4EE74EH2,>@; Jg_K_L &$, ,%'$$ +#"&'532>7##"&546632'"326654&&Ge6'1F[6RA\q8gEDn@>OCF0F'"DMyHK .Oi:"1qgKl:ERTEO'< +T8H& @_K_L$$$" +4632#"&4632#"&H$&&$$&&$&&$ x%%$ & "@a_L  $" +4632#"&#>7F$%%$j 1B &&$ 55%XU#2t `0+%%5% )yt2N8/@,eU]M +5!5!86GGGG2t `0+7%%52y)N2 +:@7J~_K_L*($"%+ +754667>54&#"'66324632#"&% &,>;1L#(a<_h5$"" ]#$$#&71 -*04F^Q-?5**%%$ :I?M{@ G /0JKPX@&gc_K _ L@$  ggc_LY@KI%'%%&(%%$ +#"&'##"&546632326654&&#"3267#"&&54>3232677&&#"I,@,.5F5MR4_A,U %+KSrQ=o++kAvY:nch]2,81 (1<e.XG+5"%2fTAf: 5!3T4\D^jDXt]uAVA9TC}0K~1@. JfKL +!'!#3'.'!VU[QP Q3-*- ;aT"5@2Je]K]L"!"$!,  +32##32654&##32654&#a̅FB-I*sZ[ES[v_JMcPa?S &F7aj;:;3J<8E=Y7@4  J_K_L  +"3267#"&&546632&&s{{.T)(U;mIOnqT$!Q NZpl]*La @]K]L!%!" +##324&##3 ŰkV_ua"lPua )@&e]K]L +!!!!!!!q#5ONa #@ e]KL +3#!!!!Z"OO= ;@8Je_K_L%%&# +3#"&&546632&&#"32675#:vKoOWuiU@"D"a@K^L +33!aZ8Pa*'@$ JKL +!##333#467#SYri9OI64f a@JKL +!###33.53iSh}TQ#h7q@K!=@_K_L$%&# +#"&&54663232654&#"KkoHHpkKryyqpyzrfo\\om\[oa* 2@/e]KL       +2####32654&5}kRZ[HfdYnd;g@MBOED=V +@(J_K_L$%&A +#'"#"&&54663232654&#"ig oHHpkKryyqpyzrf"\om\[oa_;@8Je]KL  +2####32654&&*A$iZfkWPTef9L. 'NECF;3).@+J_K_L%,%" +%#"&'532654&&'&&546632&&#"u5#0(!`S8R,M9/$0'5J !@]KL +!##5!#CZ{OOZ!@K_L#$ +#"&533265<|^Z]^aW2JwEw1W`gQX !@JKL  +#3667XZ^66,M##N- '@$JKL +#.'#36673667[   [^o  ~] n6;- U./L.V&'\,N.\"%W/F @ JKL +!##33Ff_d_6tV6@JKL +3#3aZbk_K& )@&J]K]L +!!5!5!!xD6PDPb0@a]L +#3#30hH( k@KL +#` W6b@a]L +3#53#VH& 'dD@Jt +D3#&2N <gf dD@U]M +D!5!@@(^ &dD@ Jt  +D#.'5 !%;:1 75 99 .!&u@JKPX@e_K_L@#e_KK_LY@$"  +2#'##"&5467754&#"'663265 b^@#NCI`~[:5*L!#`OdM7+C[!V^L,*MRPW C4B83-*KNU0!JKPX@K_K_LK)PX@!K_KK_L@!_K]K_LYY@!!$' +36632#"&'##"32654P?dyzc?P?VAAXHG";".. Dbgcijd7"7@4  J_K_L  +"&&546632&&#"3267,Hn?ArH(M@ML+DA :z_c|: I ag N7" JKPX@K_K_LK)PX@!K_KK_L@!_K]K_LYY@"" +"&546323&&553#'#'26554&#"dxyd>OXG P1UEBYGGG .! 3H"0I]^dkq_`j7"C@@  Je_K_L  +2!3267#"&&5466"!&&$Dd5YP3O*)P7MtA;kF?I>"zZX~DHQHDU\@JKPX@_K]KL@g]KLY@ %% +###5754632&&#"3LX^^[S6*,+,)h[ E ;?#7"+@  JKPX@"_K_K_L@&K_K_K_LY@ &$+ +  +2373#"'532655467##"&546"326554&5U Fu{vKOwEO6phuusCJHGQJL"()Gst"Q*QF - QJkcciWam`UPJK)PX@K_KL@_K]LY@ "& +36632#4#"#Y4acWxZCX(#)*]gWe^N K PX@_KKLK PX@_KKLK-PX@_KKL@gKLYYY@       +2#"&546#AX @ JK PX@_KK_LK PX@_KK_LK-PX@_KK_L@gK_LYYY@   $" +4632#"&"&'532653N8&   *XHG#1kKUU O@  JK)PX@KKL@]KKLY@  +3>773#'# gj=Ws4 5U(K)PX@ KL@ ]LY +3#3XXUV"!]JKPX@_KL@K_KLY@ !! +2#4#"#4#"#336632366[ZWmNCWnQ>XG U0~&\"^gYZVYd^I*)Z.,U"PJKPX@_KL@K_KLY@  +2#4#"#3366W`bWxYDXG \"^gWd^I*)7'" @_K_L$%%" +#"&&5463232654&#"'sGo@tHp?kKRQLLRRJ A}YA{Y_oo__llU0"#k JKPX@_K_KL@!K_K_KLY@## +2#"&'##3366"326654&Tcyyd>QXH N1RDAX0@G". 4I#0J\^ck5^<\n7""hJKPX@_K_KL@!K_K_KLY@""$' +5467##"&5463237326754&#"Q@ay{b?P FRFDWHFF0"00#I/[^fiq__kU"fKPX@ J@ JYKPX@_KL@K_KLY@  +2&&#"#3366O" )H+XH S"Q-Q6b,@3").@+J_K_L%,%" +%#"&'532654&&'.54632&&#"tb8Q [/C<954J(oZ1U%"J'69=33H&NPP+$ (8,DJF#(9S@@=J]K_L  +%267#"&&5#57733#* 4*G,LM#4/>C HA8*#r{D1/OLJKPX@K_L@KK_LY@ "$ +#'##"&533265H \4abYwYEG*']f_d^!@JKL +333>73^rr^6235< "'@$JKL"" +%&&'##33>7336673 \ `d[J  _`\  KZ.)NN*+X27.#PX. @ JKL +373#'#Թdcdc'@$JK_L%# +336673#"&'532677^tm_XN$ .8)H!Q)0LZF4+G' )@&J]K]L +!!5!5!!x p#:DBnb\,@)Jgc_L +&&554�\\j?;;?nX4;mm:5NP3+I*2PNH+1gg1+8(K)PX@ KL@ LY +3#II b`2@/Jgc_L +56655475&554&'53 4;mm:5\j?;;?nH+1gg1+HNP3+I*2PN2 <dD@1JHGWg_O$$$" +D&&#"56323267#"& $/>0H:.$/>1G:? "N5  "M6 HJ" @a_L$" +#"&546323#$$$$\:l&&$ [!n@ JK1PX@hgKL@#hW_OY@!!$% +&&#"3267#5.546675a%FBRMOL,A:'C;W00W;P I fgh_ M ad T  H@EJe_K]L   +2&&#"3#!!56655#53546N7W#J(9<* +8``oF;BBh=;PJ ABiBYd;B!1=@: J HGc_L&*/( +467'766327'#"''7&&7326654&&#"ZB1B9 7C0@#?/C8@0B0AC";$$;##;$$;"a9D/@@/C9?1B/@#@/B9$;"";$%;##;,3@0 fe KL +33#3##5#535#533\|Vz]m]@R@@R@w8,1>8(32'2>54.#"7"&546632&#"3267Pc66cPLe96cP@pV0.SqDZP.SrScb.ZAA:2+;A9B92 6cPPc66cPPc65.UrEArV1Q[ArV1Z{eAe9=UIMR @  4$@JKPX@!_K_K_LKPX@g_K_LK%PX@gc_LK&PX@"ggW_O@)~ggW_OYYYY@"  +2#'#"&547754&#"'663265AB/ 9%/88*3@h0<*3-6;*12c! 1 /((8  0+7'77'(??ƪ>>$% $%2%@"U]M +#5!5GqG(31&4=idD@^/J ~g  ge W _ O''=;75'4'43210*(&&  +D".54>32'2>54.#"'32#'#532654&##Pc66cPLe96cP@pV0.SqDZP.SrERL0tVd>2',(,1 6cPPc66cPPc65.UrEArV1Q[ArV1_A@/7 ­' # : dD@U]M +D!5!B7u 9dD@.gW_O      +D"&54632'2654&#"HWUJFYYE0-/.1..UDDVVDDU;4*,44,*42 V 1@.ee]L   +3##5#53535!AHHGGGG3U0@- JgU]M%( +!57>54&#"'663232s))%1#E+@I;8Q6p'1&!.?71N5MAU(M@J&%JggW_O#! (( +2#"&'532654&##532654&#"'66GH+'/UX%@F>40:4992/)5$DU>0)3 2):I ?")#$!7'.(^ &dD@Jt  +D#5>7 19:$"  99 57U\@  JKPX@K_KL@KK_KLY@"$ +#'##"&'##33265GO8'8XXxYDH(*=(d^7%QJK)PX@~]L@~U]MY&# +####"&&54663!%:f:'>\37dA?.l[_n.H+ +3+2dD@'JW`P$" +D#"'532654&'73JJ  $&5&+:$3057V5(%L '@$ JU]M  +#467'7G  6#LT*  '1\ Y >K%PX@c_L@gW_OY$$$"+#"&5463232654&#"YVHCXTIGU+21,,11,)QYWSRWVS;::;;99'8  0+'7'7'7'7ժ>>ǩ>>%$ %$"$ddD@Y !JU e f]  M +D33467'735#533#'35467~KL#  6#IkI==} 6*  '1\T`4<`]8 1*bdD@W Jh eU] M**)("  +D33467'7357>54&#"'66323`KL  6#Is(*%2#E+@I<7Q6*  '1\T6p'1&!.?71N5M>(,7@dDKPX@"= 0 J@"= 0 JYKPX@7g g  U g   f ]  M@>~g g  U g   f ]  MY@+--))98-7-7654321/.),),+* (( +D"&'532654&##532654&#"'66323!5#533#'35467%@F>40:4992/)5$D/GH+'/U@KLI==}  ?")#$!7'.>0)3 2):I6`4<`]8 1@"" 3+~&$C3+~&$v3+~&$Jo3+~&$Q^3+~&$j3+~n&$O==3+58@5ee ]K]L +!!5##!!!!!%3#5k]S:ONM=Y&&za&(C3+a&(v3+a&(Jb3+a&(j3+'*&,C3+(7&,vF3+U&,J3+6&,j3+ ?@<e ]K]L   +2###53#3#3 4&=kWűJJnZ"Pr:NBMNa&1Q3+=&2C3+=&2v#3+=&2J3+=&2Q3+=&2je3+@> 0+''7'72244>3334= )<@9$# JHG_K_L',*# +#"''7&&5466327&#"4'326KkpI0=4,,Hp4Y%.=3^?4Nzr3E*yqfo\/D(J1Wm\B)Gc>c%#J:Z&8C3+Z&8v 3+Z&8J3+Z&8jL3+6&<v3+a* '@$eeKL$"!# +###33232654&##*4}mQZZ`~HiaWbY~54&#"#46632 ** &%6>hR/HM(70)5?.))G8#=%X:d?awi"3' $K;UNO.($1#);(,! &*&/*HCO#J.&DCn.&Dv.&DJJ.&DQ9.&Dj.1&DO.-",3>@$*#  JK(PX@%  e _ K _L@*  U e _ K _LY@#.-<:6410-3.3(&! ,, +2!3267#"'#"&5467754&#"'663266"34&3265[A^3OJ1M&(M2>#[MIax|Z=3(M!#d1>QT5:C9K^H3*?U"YU&QQU7'&RC7'&Rv7'&RJ`7'&RQO7'&Rj 2y G A@>geW_O      +"&546325!"&54632!! !!  "" GG "" 7'6&<@9"!JHG_K_L&,)" +#"''7&&546327&#"4'326'sI8(:-!tI:';-"k $4RJ:"4QL !8'>$dA$8&?#c>&A2l_J1oO&XCO&XvO&XJfO&Xj&\vU0&]JK)PX@K_K_KL@_K_KLY@ %$'" +#"&'##3366324&#"3260yc?PXXN@cy[FJSDAXJE .  " - "0ee\\ckk&\j~W&$L3+.&DL\~&$M3+.&DMZ$~&$P.$!&DP,=Y&&v3+7&Fv=Y&&J3+7&FJM=Y&&N#3+7&FN=Y&&K3+7&FKKa&'K3+7&G'z7^*  JKPX@'eK _K _ LK)PX@+eK _KK _ L@+e _K]K _ LYY@&$** +"&546323&&55#53533##'#'26554&#"ewyc?OXLLH P/TEBYGFF .! 3=BYYBH"0I\]ehn``iaW&(Lt3+7&HL`a&(Mr3+7&HM^a&(N3+7&HNa$&(P7$")0@%&JKPX@(e_K_K_L@%ec_K_LY@+*.-*0+0"&&%! +3267#"&5467#"&&546632!3267"!&&-52)'MtA;kGDd5YP3O*)+b?I>t-82,"?>zZX~DW&,L3+&*LJ&,M3+!&*M($*&,P\$&LP(*&,NQ3+(B &,-SN&LMB4&-J3+,&,Ja#k&. WU# &N U &@# JKL +#'#336677iB]]  6(L  P&/v(3+E&Ov3+a#&/ 9A#&O a&/' Ұ3+UQ&O'a&/N# 3+U:&ON Ұ3+  ,@) JK^L  +35'737!a1#TZ$8<2Q?dP  ?@ JK)PX@ KL@ ]LY@  +3'737N3$WX@%e ;8,;Da&1v3+U&Qva#&1 U#"&Q Ba&1K3+U&QKd_&QFaB;@8J IcKL +"&'532667##33&&53& &0mSh}TfL0,QFP%} p8t#"&U a_&5Kf3+G&UK3&6v3+3&Vv3&6JN3+3&VJ!3&6z3"&Vz3&6KL3+3&VK #!&7 ##S&W !&7KE3+&W' !/@,e]KL +3#535#5!#3#蕕ߔEJPPJS R@OJ e]K _L   +%267#"&&55#535#57733#3#* 4*G,DDLM#4/>C HA|Bz*#r{DzBz1/Z&8Q3+O&XQUZW&8L3+O&XLxZ&8M3+O&XMvZ&8O3+O1&XOZ&8R3+O &XRZ$&Z@JKPX@K_K_L@cK_LY@ #&%" +3267#"&5467#"&533265352 '.Z]^aWY,,,*k843= w1W`gQ2?j$2EO$&XPP &:J3+ &ZJ6&<JL3+&\J06&<j3+&&=v3+'&]v&&=N3+'&]N&&=KQ3+'&]KUjG@  JKPX@_KL@gLY@   +"#4632&&)/XaP1*4?AgU E ]#N@K Je_K_L ## +2&&#"3##"&'53265#575465),(WP$  *(iiXD /=ED*bNI,;)AhN (1[@X. J  ~gf L *)$"((    +56673&54632#'!2654&#"3'&&'0j .61=0/A]RN ZT= D..`?2881. 8;. ">I@< ; ) JKPX@< gh e _K _L@@ gh e _KK _LY@,$# GEA?9742.,('#>$>""    +#56672#"&546"32654&2#'##"&5467754&#"'663265 8@?0/@?01<<1  b^@#NCI`~[:5*L!#`OdM7+C[ $$ 5713882271V^L,*MRPW C4B83-*KN5&v3+.-&vS=&v$3+7'&v3#&6 3#"&V (^z)dD@ Jt +D#&&'#5>7 -1>86<0, 75 // 57(^z)dD@ Jt +D.'536673 ,0<88>1- ^64 00 46(^Q'dD@U]M +D!5QGG(^_ .dD@#W_O "" +D#"&'33267_QHJK63.'9)'(q (dD@W_O   +D2#"&546\(^1 9dD@.gW_O      +D"&54632'2654&#"1<<1/@?0  ^822771382($,dD@!JHW_O%! +D3267#"&54667p-52+0""t-82,7, 5(^4dD@)Wg_O"""" +D663232673#"&&#"(9/5028/51^;E;E(^ =dD@2 JU]M    +D#5>7##5667 .62  P .621 99 47 99 V"^% -dD@"JU]M +D5>73 ^#^BD CGwF !dD@ JK PX@&n~W`P@%~W`PY@ !!    +D#56672#"&54632#"&5467* sF S# T"l~&$S ˰3+H&y3+E&(US ˰3+&+US ˰3+&,}S ˰3+&2.S ˰3+'<S ˰3+&u%S ̰3+HF&Ta~$aT%a;K1PX@]8K9L@]8LY@ +!#ZP1L@ JK1PX@8K^9L@b8LY@+!5&&'O} l67t-T$$S*a(&=a+=/@,e_@K_9L$%&#+#"&&54663232654&#"!5KkoHHpkKryyqpyzrfo\\om\[o[NN(*,ak._ :JK1PX@ 8K9L@ 8LY@ +#&&'#^_ _6.T$$T-=a*0a1# eK1PX@ e]8K]9L@ea]8LY@   +5!5!5!7llX{OONNOO=2ay>K1PX@]8K9L@]8LY@ +3!#!aY6{a*3$"T@ JK1PX@]8K]9L@a]8LY@ CA+355!#*'263!$0, %L(J+ KPO !76<3'jK1PX@! gg 8K9L@! gg ]9LY@ ' '"! +#5.5466756654&&t8FvYY[wD9sQ^(fqYtc(_XHxH0_M0nn1O^.FxJX0T7Yh~kV9S/F;5NK1PX@g8K9L@g]8LY@ +##5".553332655DwZXZwCZfpXrd3^J+,J]2]]\][&!VJK1PX@_@K]9L@a_@LY@ !!+"!53&&5466323!56654&xpJ]@XLijLW@]KqrdCHO1pbONbq1OHBcr6&,j3+6&<j3+7X%&}S+%&SU%&S"RH%&S^O/F&T7X"#0l@ JKPX@_CK`9L@;K_CK`9LY@%$,*$0%0 ## +"&54632366733267#"&'#'26554&#"bzxl;O E  %/ M4RFAXIFE *((HP$@$."0I_gdijeeeUJ.N@KJg_BK_9K=L*('%!..  +2#"&'#466"32654&##532654&DCh;NJ[]s:O X>lC(D)#K3VN`N5+NHN+T@HT  b[gnQe0IF?TLGOIJJ=><"@ J;K=L+#466733>7 _ [q j)[W"T])@;<@6&!/3@0J_:K_9L+)!!+2&&#"#"&&54667&&54632654&?Eb'&%T3-*:2[aqHo?7_;8Dg[A8#QILSC"E)'(1uWx~4dH@`@ L8EG/G3BTYSCU+"(E@B   Je_CK_9L('%,%#!+#"3267#"&546675&&54632&&#"3cIR<7V!V>sn!6 -7s[:S(!!E/ySF;H\1(MYC(3 ;1DJFL,&7=&@J]:L_+#6654&&'&&54>7##5!'W&36_b0Sl;,A"xtg}>(L6LA(,PJ gcK}nh5IBWnZ(9; 7U"|JKPX@_CK9K=LK1PX@;K_CK9K=L@_CK];K=LYY@ +2#4&#"#3366W`bW:>XEXG \"^gG@Ad^I*)7 7@4e_BK_9L%#+#"&546632'"!&&267!1kX|u0kV|xLG2ILNJFyy]εz\˃RH)@&J;K_9L%#+3267#"&&5%(/ 6,E'00C IA{U 'KPX@ "J@ "JYKPX@_BK_9LK1PX@_BK9K_9L@~_BK_9LYY@ ''&%$+#'&&#"566323267#"&''.'#&+ #3@* %+I zK+1G$J:6A%,;9#P'Uw2JK1PX@ ;K9L@ ;LY+33>53#[k >EW%[S_B?>aiS6=6/@, Je]:L!%!>+746675&&546670##5!#"33#"#6654&&'&&6'@%28)C(#7Z9kDJYSV[`*N6L=&S$55ad2M3 A9/=% ID"D337CXA34 9(,PJ b7'"R sKPX@J@JYKPX@];K_9LK1PX@];K9K_9L@ ~];K_9LYY@ +%267#"5###57!#8#oWmHi>EY1&#I#O&"6@3J_CK_9K=L#"+#"&'##4632'"32654&&m)LYnDi;L(OEE G-@|rƢhege7="#+@(J_CL##+2&&#"#6654&&'.54669(M>!WLKFM=&S%467Y5Bt" I ni7Q!@];K_9L%%%#+%#"&546633#32654&'#"&8oRoGY'0lJSSJ+(ddHtDd|8I%l>UlfO@p+^ 5@2  J];K_9L%#+#3267#"&&5#575+/7.N0IJ:.B HC3'#O/$@!;K_9L +"&&5332654&'33Yc(XFMPLX CsG%VbrxFn<;oJ7"(2@/"J_CK9K=L((++4632#5.546">54&D%-/N.TJ>X0K{HVJuD:h,3R0=/1kFIW(*[^CwOa}@:xbQ0?1]F^c!#A@>! J_;K_=L ##+233267#"&&''#'&&#"566Z2/D^]%%  -9%G^R" ?;#..D!=*(-EO0@-J:K;K9K=L+6654&'3#5.53UgWJ|LVLvCW0P.JfjEuFDwBg};8xd KV&8)4@1 J~;K`9L))#%#&+#"'##"&&5467332655332654&',U>l" m>U,Z<11/T2-2<FNPzDZZDzPNFFOacJ8>DcaOFH&j`O/&j7'%&RS O/%&S8%&Saa&(j3+ KPX@ J@ JYKPX@ e]&K_.L@$e]&K'K_.LY@  +"'53266554&####5!#321+-:FYٿdnf N 0.@:8{OO]XFe`a&`v3+=fF@C  Je_-K_.L +"!!3267#"&&546632&&j \}y1X*NqtFPqAc)%#TvtN N\on\M36(*,6&,j3+B-#,VK PX@ JKPX@ JKPX@ JKPX@ J@ JYYYYK PX@ g]&K_.LKPX@+g]&K_.K_.LKPX@ g]&K_.LKPX@+g]&K_.K_.L@(g]&K]'K_.LYYYY@,*&$## +"&'532667>7!32###%32654&##B# "T;iy4~  &??]X`d0 K/I'(o6\9_r{J4D]0XACE8a3@0g&K^ 'L%! +33!332##!%32654&##aZ2[:iy4~?\X`c0.6\9_rMMACE8 -@*e]&K'L#!+#32#54&####5dkZ8CZP]X:7zPaj&v3+ p&&3+aDy #@ &K^'L+!##5#3!3y\ZeYz~$a4 1@.e]&K]'L !+3!!32#'32654&##ajkv.vwn`NVg_O5[;boMACE8aT%a`D3@0Q]&K]'L +3#5!#3>7#!B[VV7$A2 /9 M >OQ:6a(T%@" J&K'L+333### dVdgVgo[ZZjj&)@@=# J$Ie_-K_.L%$!$%)+#"&'532654&##532654&#"'6632\MZ^:i-.p1`cthfajiP@DX*+*{Msy#IU  YF^vRHBD>KG<6:"=+db@J&K'L+333#4667##bTdTvdx"QEO6$UFb&&n3+aj @ J&K'L+!##33jlZZ;fjZcQ@ JKPX@]&K_'L@]&K'K_.LY%'+!###"&'532667>7!cZ  &?3# #{J4D]0K1I$&oa*0a+=2ayma*3=Y& !7 p-@* J&K_.L%$+#"&'5326733667p AXD1.7Bc G_/Y 0=w  3rF;aD )@&R&K^'L +%#5!3!3VZeYOzPY)@&Jg&K'L##+!##"&5332673YZ:e>dnZ=D;^;Z%]X:9Za @&K^'L+!!3!3!3ZZ[zzaD-@*R&K^'L +%#5!3!3!3VZ[ZOzz 1@.e]&K]'L !+3#5332#'32654&##qdt1z}tWRZ]f{O6\9_rMACE8a 6@3e&K^'L    ! +3332#!3%32654&##aZnct1ykZqVRY\d6\9_r6LBCE7aO +@(e&K^'L !+3332#'3254&##aZcw4`\{6\9_rME8;F@CJe_-K_.L+"'6632#"&'53267!5!&&2R!%)j8sJLt>V**V0Z K\fu\N Om{a"KPX@e_&K_.LKPX@#e&K_-K_.L@'e&K_-K'K_.LYY@ $%##+#"&&'##33>3232654&#"GgfJZZJcgIksukjttlfo\Ti_M[o3@0Je]&K'L'+#.54633##"338i&C*ZlVZX\h(8 .P@ag6(U;DBH.!D9!+1@.'JHg_.L$"+++4676673>32#"&2654&#"9jvA|6#XVAL1E,hj>oHoAP=F-G1 #?B Mlp(kZw;aTfR_'21\I+U!/@,Je](K]'L!#!%!)+##324&##324&##326yFDBF28 9&#.('U@](K'L+##XJ2F1 3@0Q](K]'L  +3#5!#3667#3NUT+EEw!5#2_|ED07"H,@) J(K'L+###33dRd`R!"(J@G'&Je_/K_.L$" ((+2#"&'532654##532654&#"'6\m7. 6!ov:^"]78I~=5$>0LRդ/,17&Hj *@ JK1PX@* e _ (K]'K_ *L@( e  g]'K_ *LY@%# ** +"&'532654#"##53533#36632 $wYDYLLXZ4bbDH#0d^]AZZAX&)*]ggLUU&v7"F@C  Je_/K_.L +"&&546632&&#"!!32676JsBDuI)NCMPPN-FD 9yad|9 H NPHYV L3"VNL &*j_M!KPX@ JGK"PX@ JG@ JIYYKPX@! e](K_'LK"PX@+ e](K_'K_'L@) e](K]'K_.LYY@!!$#$! +32####"'53267#32654&|iees} .L8 6Blo:IEMKKYΩ^Aګ(00#U@8@5 e (K^'L$! +32##5##335#32654&xkebtZZnp:IDLKKYګ(00# U&v&\&UG #@ (K^'L+!#3!3##XXV2a]%@"]&K'L+!#!5ZH]ʓUFKPX@&K](K'L@](K'LY@ +##35X, &:C&3+ &ZC &:vm3+ &Zv% &:j3+ &Zjg6&<Cp3+&\CT(3@U]M +75!(NN(3@U]M +75!(NN(3"*dD@eU]M +D!5!!5!aaZ@@  @]L  +'66730A  45&WU#  @]L  +#>7 1A  55%XU#t 3+  @]L  +#&&'7r A0#UX%55  [$@!]L    +#'667##'667[_ 1x^/:4 46:4 46 [ $@!]L    +#>7##>7T 1B [0@  55%XU# 55%XU#nt  3+A 7@ JK)PX@ KL@ ]LY +'#5'37dd W<@@ JK)PX@ KL@ ]LY +%7'#75'75'37'eeUUUUM+ @W_O$" +4632#"&M@/.AA./@mC99CB::Hy&' 1h %1;EKPX@2   h g_K  _ L@:   h gK_KK  _ LY@;=<32'& CA %H&A@@KL +#@LK67]gGQ)&f 3+-7@4ee]K L +35#53!!!!3#UU痗AOOnA!&Z@WJ  e e_ K]L#"!  && +2&&#"3#3#!!5665#535#53546P8W"I)5?& /5aaaa_E:BXANBACPJ JFBNABguL ,@* !JKPX@/ eg ] K  K`LKPX@3 eg ] K  KK`L@6   ~ eg ] KK`LYY@% ,,)(%#      +2####32654&3#3267#"&55#577҅v1tfW)\[RHnn( + 7@MNnd>6"*A@>) J~gW_O&$""+%2673#"&&5556675466324#"67#43KI)F+0.?4:E1V6'S<&z:-:RY!LAq;(D(MFAlO2;\3)@_!-1]@ZJg  gU] M..#".1.10/)'"-#-!!+3330.53##0%"&54632'2654&#"5!_eEOb@TPG@URD,&&,,''V&<@6N'=CtXRRWWRRX:97855879EEjC@@ J  U]M +33#5467###!#5!#E^^a[@e5`e fj`/ (*66&u28"I@F!JgeW_O"" +"&&54>32!32675&&#"5Us;.K\.IvDlN-IV"#;TTL42GN~HHhD C|U%<6%>%>&" )5B@ =$JKPX@#h ]K _ L@'h ]KK _ LY@"766B7B1/)) +33467'73"&5467&&5466326654&#"2654&''nKL  6#InIN- !&?%7P*'/SA%$ $(*(-& !"(6*  '1\T@8)6+&$157%06)8C !"$& )$(,EQ^0KPX@" Y@3 J@" Y@3 JYKPX@5  h  g_K_K _ LKPX@9  h  gK_K_K _ L@=  h  gK_K_K K _LYY@+SR.-))R^S^MK;9-E.E),),+* (( +"&'532654&##532654&#"'66323"&5467&&5466326654&#"2654&''%@F>40:4992/)5$D/GH+'/U]KLIN- !&?%7P*'/SA%$ $(*(-& !"( ?")#$!7'.>0)3 2):I6@8)6+&$157%06)8C !"$& )$#";GT@  O6) JKPX@5  h  g]K_K _ LK1PX@9  h  g]K_K K _L@7 g  h  g]K K _LYY@*IH$#HTITCA1/#;$; "" +33"&'532654&#"'73#6632"&5467&&5466326654&#"2654&''KL7 FE-550% CZTsIN- !&?%7P*'/SA%% $(*(-& !"(6 C',&*7mD@FM@8)6+&$157%06)8C !"$& )$0 #/<@ 7JKPX@+ ~h]K _  L@/ ~h]K K _ LY@$10 0<1<+) # #   +33#5!"&5467&&5466326654&#"2654&''aKLI'IN- !&?%7P*'/SA%$ $(*(-& !"(6p<1@8)6+&$157%06)8C !"$& )$e^ &@#W_O ""+#"&'33267W_bQR.5.5KMLL6%'4X6 >JK)PX@ ]L@U]MY@  +#5>760  69 56#@ ^: >JKPX@ ]L@U]MY@  +#5>7:W! 58 69 UO 6@3JUe]M   +##5#533#5467U=KI= P``4]8 1u@LB@?JegW_O$%$# +#6632#"&'532654&#"'7+ CZTR FE-550%L7mD@FM C',&*CL*@'JU]M +#5!O'p<1ET$18@5JgW_O,*$$  +2#"&5467&&5466"6654&32654&'7P*'/SBIN- !&?$ $(%%.!"()*(-&T57%06)8C@8)6+&$17" !)$$& )E +:JV^bfosw}!K PX@B / .JK PX@B / .J@B / .JYYK PX@5  p)%!&&%p  4321e  U W  g7  geU6"g$"#!%"!e/-+(&''&U/-+(&&'^<0;.:,9*8 '&'NK PX@5  p)%!&&%p  4321e  U  g7  ge6"g$"#!%"!e/-+(&''&U/-+(&&'^<0;.:,9*8 '&'NKPX@5  p)%!&&%p  4321e  U W  g7  geU6"g$"#!%"!e/-+(&''&U/-+(&&'^<0;.:,9*8 '&'N@5   ~)%!&!%&~  4321e  U W  g7  geU6"g$"#!%"!e/-+(&''&U/-+(&&'^<0;.:,9*8 '&'NYYY@~~xxgg-, ~~x}x}|{zywvutsrqpgognjhfedcba`_^\YWUSOMJH=;7631,:-:*($"   =+53#5!53!53!5353##53#53#"&54632"'532655332##'32654&#"32654###53#5332654&##53#53533!5353!53!5335355^j5566G>BB>>BB>2 =6T575.e "" "" ' +T66j55B$266j55`6^x_56^666666^6^BQQBCPP22-! ) "',-33--336K򄄄_55_555555)d+C@@JGU_O*($"%-+ 54676654&#"663232654&#"56!++\P*X"(!>!& ())(66{">1CJW"7'##%*&,K `3=U@RJ gg _ BK_9L54;:4=5=.-(& 33 +23##"&&54654&#"'663232654&'.546"&& nzF@;y]GQ  11(.8X]}CSX++0m] XI i^3Q-)M> 4'"Q-*B  8^:?VH,&%;#go7K(PX@  J@  JYK PX@_@K9LK PX@_8K9LK(PX@_@K9LK1PX@8K_@K9L@8K_@LYYYY$&+>76632&#"#3/-2(  &,+[be1nb&&F!I\b. 9,D@A J~] ;K`9L(&#"#% +##"'##"&5467#57!32655332654&9{c]l"#k\c"F$;200U4,2:I;{;usZZsu;|:&#I5|;]GJ8YY>DH\;za*&0vb3+UV&Pv{~&$F.!&DFc8 9dD@.gW_O      +D"&54632'2654&#"1<<1/A@0 821981382=%$QJK)PX@K_K_L@_K_LY$(&# +#"&&546632665332654&#"JkpHHpR|)*_ 9?-qzzonz{qfo\\om\71 L4 ;dU|7j#/@, J_K_L$)%" +#"&&54632665332654&#"'sGo@t4Z -^9:kJSSJLRRJ A}Y$! N2 E] M.eiieeffZ2Q JK)PX@KK_L@K_LY@ #) +6653#"&53326651]%H=8x_Z_`AO$aM; /Q7 JwEw0V`/S5OkYJKPX@K_L@KK_LY@"$ +#'##"&5332653665$G5_\3L)4l0T8w94;#(@%J(K'L##+#&&'#.'336677&&'33667ZVR<vP*N3W)7  J X"46I4;Ch_251j1QBV o9@6ee&K^ 'L! +3#53533#32#'32654&##[^iy2zmc^T\eTLffL|6\9_rLBCD8 E@@=  e](K^'L#! +3#32###535#32654&թgtuu揑;MGlIKYIln(00#a}%KPX@" # J@" # JYKPX@" e_&K _ .L@* e&K_-K'K _ .LY@  %% +"&&'##33>32&&#"!!3267mJZZ Sh8d'$"O1k~R}w/T)(V Ug^OLxqN~ NU"$KPX@! " J@! " JYKPX@" e_(K _ .L@* e(K_/K'K _ .LY@ $$ +"&&'##33>32&&#"!!32672FoCXX DlC)L?MN ,A@ 4nWRg0 H MPJ L *@'f&K'L +#####3'&&*_FRF]*+#' 6JJX.2Xa<7 *@'f(K'L +#'##5###3'&SZc5O7aZ8;.2JI=a2@/ e &K'L +#######333'&&x)bDQE`ZZ~+#$ 6MMM.X<#Z`:U2@/ e (K'L +#'##5##7##337#3'&&#Yd5O4dZeVV_8  ;9?G2  =@: Jg] &K'L +#'.##"#7>7'5!BL,B\B72Z25A`B+KAB.Q8/4S4/7Q/BQx <@9 J~](K'L+#'.##5"#7>7'5!86<"?X? +&Q)* @W?"<63'@("&'"(?'3Ha"%K"PX@ ! % J@ ! % JYK"PX@ g ] &K'LK-PX@%  Ug ] &K'L@&g  e ] &K'LYY@$#""  +#'.##"#767##3!'5!BL+CYC"61[26 A^FZZ[B.P814R4-QBQUK#&x@" & JKPX@g ] (K'L@&~e ] (K'LY@%$## +#'.##5"#7667##3!'5! 6<;953.(#UU +2&&#"326632&&#"#"&&54676654&##532654&#"'667&&'53> 5X\aNZd78"2,>8",2 61 4=,EM exbYxdfbiiP@=^*,%V5?@<*2U9*! ^CIV  VG^o U#;#Ti@fLQIF E$J%G~ gga_.LNMCA=;:842,'"TT +2&#"32632&&#"#"&&546676654&##532654&#"'667&&'53>y 1;E8/ 7"oz43".5]%!& ,#h7;B"RFHXMNF:ES?;'H(:!6@4*39&C419  4(CY J #5!7#(2.+H%-&&F ; 0,5tO=7@4e_-K_.L&#+#"&&546632%"!&&267!KkoHHpkKpr  oprq-qfo\\om\[rryy7'" 7@4e_/K_.L%"+#"&&54632'"!&&267!'sGo@tHp?JJ8MHMJM A}YA{rQOOQgZVVZR@  JK(PX@_&K'L@&K_-K'LY@+"#36677>32&&g#$g^ P'90! @F71N&'X1GX(JfK-PX@ J@ JYK-PX@_(K'L@(K_(K'LY@ +2&#"#336677>   {u\ F!/D(*z*?G#4:&d ^3+&e )=6E@B!6/.J_-K(K_.K_*L%#$%&#+#"&&54663232654&#"%336673#"&'532677EdgBBhdEemncbnne)]wk]ZM$ .9fo\\om\[o+'H"Q(2LZF4+G7G"&R\I=26@3-'!JgW_O+) +"&'.54676632'66326654&'#"&'%[}@%$W}CB|X%a$$ \]]\$$[__;bbabbatsst7\L-.@+ +&JgW_O***$+#"&'&&546766324&'#"&'663266\pc7_uqd _t[;>@::A2 ?: t0usrQddSSf$e= !X~@{J-I. =: W J~   ~gg _ -K  _.L#"VTNLGEA?<;8620+)"X#X""#+5463233#"&&#"5654&&54632"&&546632&&#"32675332654&#"'6632#"'P=5&IR38XD4);!<]|=>tP&K"4RZfe7Z9 ef[R4"K&Pt>=|\hGG56>9$ #'9_omYCCYmo_>>:Nq U@G*F+ :7 JS I~   ~gg _ /K  _.L"!QOKIDB><9853/-(&!U"U   +233#"&&#"#54625654&&54"&54632&&#"32675332654&#"'6632#"&'&IQ39XC4@MD"4X6"DK?=*9"dr|j8QPq?955k"(9 # &C je^ll^ej C(""(~s&P3+&Qc3+<f:@7J_-K_.K*L +2&&#"3267#5"&&54668i)%"S2vv,Z|FSM_kl^7":@7J_/K_.K*L +2&&#"3267#5"&54669(OCSQRP ,XCu" I bii` 意d|93-t 0+'''7'77'7;Z"d!Y<:*7*75310.,))'%#"  ""(+D6632#&&#"6632#&&#"!6632#&&#"6632#&&#"!6632#&&#"6632#&&#"!6632#&&#"6632#&&#"2205'% 2205'% 2205'% |2205'% 2205'% K2205'% 2205'% 2205'% Y+45*,35*,35*,35*,35*,35*,35*,35*D#,5>GWdD@L75,+('# <;21JeU]M???G?GDC+D#'667'&&''766&&'%&&'5&&'%'66#667 D !40'"$P0"U)^$&X&&X&)^$2(!5j0"U'"$P' !/ )^$&X&k$P0"U'!50( D !/ !/ D"U'"$P0'!4A&X&)^$aD %L@IJ g   a&K'L%%$#"!   +"&'3326737#4667##3333bPQ.5-6SXsMSudTcbHKM6%'4KMALKw!MDPUG "M@JJ g   a(K'L""!    +"&'3326737#4667#333IbPQ.5-6SXH=RlSl\?^LL6%'4KM=2/? K24>@;e e &K^'L%! +3#32###535#3254&Zl~5JJbf`ZN5\:bo"NZD8 >@; e e^'L$! +3#32###535#32654&okhtLL掐Cw(00#a16@3Je]&K'L(2!'+'###323267'76654##12993G0CWZċO$27A_9dK+] nB*S9+U0"-z@('&% JKPX@_(K_.K*L@!(K_/K_.K*LY@$"-- +"&'#0#336632'"327'76654&S>QXH N@cy.)74?!8RDAX:7=G . "* I#0Tu"K)T \^ckK)OR8ee -@*e]&K'L +!3###53ZJJPN:NB -@*e](K'L +#3##5#535XLLJDDag z@ JK1PX@#g]&K'K_*L@ gc]&K'LY@   +"#!!6632#"&'532654&7Z;DyM.?>"Z]:PmF P {xwzU  G@DJg](K'K_*L $%%#+#6632#"&'532654&#"#":b<&9:#?CUX"XJay8N `ficDu8@5 J&K^'L +3#5###33K_V2VgdVjjo[ZZG 8@5 J(K^'L +3#5###33ݯbU0Rd`R&$&^!$"&^aD1@. J&K^'L+3#5##3\lV;ZZ;jZUF1@. J(K^'L+5##333+XX`Zaj.@+ Je&K'L+%#5'#375373#'5==ZZ==f5lɌDCb"U4@1 Je(K'L+73#'#5'#375%m`fz@8XX8S|6\?@ j3@0 Je&K'L +53533#3## TZ^^;fDlZ&OUUOZj& =@: Je]'K(K'L +3#3###535`fXLLZA]AZ +@( J]&K'L + ###53DlZ;jzPZk +@( J](K'L +###5!XeVHaD0@-ea&K'L +5#!#3!33YZZoYVM.UGw0@-ea(K'L +5#5!#3!533 PXX#XO2a' -@*e]&K'L +33!3##!aZnZ.PMU -@*e](K'L +33!5!##5!UX#XH0a"w@JK1PX@$g]&K'K_*L@!gc]&K'LY@""4%%2 +6632#"&'532654&#"#!#`7CwN/>>"Y]ul9YZkG P |vxyyU B#I@FJg](K'K_*L##$%&# +6632#"&'532654&#"#!#!FqB5[8$64 9@9")#JKPX@) g_/K_.K_.L@& gc_/K_.LY@433>4>-+'%! 22 +2&&#"3267&&54632327#"&'#"&&546"6654&!) $P?F9$ZCAU9'  #%D2%Om8v "#$ ("Gne9Z3X:\VT^DaF J|K;51KK43;=$Y&&^ 7$"&F^ D! *@'a]&K'L +5##5!#3BZVyQQG *@'a](K'L +#3#5##5ƮOVPIzI6<@J(K*L+#5336673*X\po\(YX)&61@. Jf&K'L+35#535333#baO_KO/@,Jf(K*L+3##5#5333667цX\nkCC.N!!Q/Dh/@, Ja&K'L+5##3332_d_ݺV6tVF/@, Ja(K'L+5#'#3733(c¹dcN DG1@.]&K^'L +5!#5!#!33 dZYyQQzG1@.R](K^'L +5!#5!#!33lBXQII{1PD8@5Jga&K'L##+3#5##"&533267YVVZ:e>dnZ=D;^;%]X:9ZJF_8@5Jga(K'L"#+3#5#5#"&55332675OWP-W=SZXg2R+2!VH\PY;@8Jge&K'L+##5"&53353667Y["F&=otZ@I='G 6# Z[9: \J<@9 Jge(K'L+#5#5#"&553536675X8 ; RXX_;8yrWGYaj)@&Jg&K'L##+36632#4&#"#aZ:k8dnZ=D;^;Z]X:9UK#*@  JK PX@(ph _ -K_.L@)~h _ -K_.LY@%$('$*%*! ## +2!3267#"&'#"&546733366"!4&j;zyCn.+nP 7FK6au]Zg3{R?5" 1P|wqf!#*@  JK PX@(ph _ /K_.L@)~h _ /K_.LY@%$('$*%*  ## +2!3267#"&'&&5467333>"!4&Fc5VP:L*)P7tADH3 Ac:>J@!J@o67 1sn?(TeAsI#8ZZ6nE P zxPg2>U =@:Jg(K'K_*L$%#+%#"&'532654&#"#373=e:$76!ax9L `gg_7wDb@ JKPX@a]&K_'L@!a]&K'K_.LY@ %'+%3#7###"&'532667>7!caHgNZ  &?3# #P{J4D]0K1I$&oGHKPX@ J I@ J IYKPX@Q](K_'LK(PX@a](K_'L@!a](K'K_.LYY@ ##+%3#7###"'53267!\@Y=X .L9 6@CJϩ^Cad@ JK1PX@e&K'K_*L@ec&K'LY@%$+#"&'53265!#3!DwN/=>#[`ZZo|nD O uz .U (;@8 Je(K'K_*L%$+#"&'532655!#3!5(5[8$659=XX"av6 N XhaD*@'ea&K'L+%3#7#!#3!3bIgNYZZoYPM.UG0@-ea(K'L +33!533#7#5!UX#X\@Z>X2PDY2@/Jga&K'L##+!##35#"&5332673YWVS:e>dnZ=D;^;Z ]X:9ZJF8@5Jga(K'L"#+##35#"&55332675OVM-W=SZXg2R+!VH\aD/@, Ja&K'L+!##3333#7#4667#S߄aHhOYrECFICAUG0@- Ja(K'L+%#7#467####33@Z>OJOuuJV-Q-/Q2(*,~&$&!3+.&D&~&$j3+.&Dj5.-"a&(&3+7&H&;C@@Je_-K_.L+"56632#"&&55!&&267!LDp0,kOpNJik; ybbyU&XR\po[[o"y}vKm;3");&j:3+3&)jT&j3+&jS&&j3+!&j#A@>  Jg]&K_.L$%$+#"&'532654&##57!5:g-/n2a`qiCGcc^xRJCC>IPA@> Jg](K_*L$%&+#"&'532654&##57!5DpBAwQ;^ !a;M`o[;@5aIGm=PYMTK=JbW&L3+U-&Lb&ji3+U-&j(=&2je3+7'&Rj =b7'"c=&bje3+7'&cj ;&j3+&j pW&L3+&\LB p&j$3+&\j p&R3+&\R[PY&j03+J&j aD (@%a]&K'L +!3#5#UUZPUG (@%a](K'L +#3#5#OWPIza&j3+U&j_:&{_L:R@OJ  ~ e d](K'L  +"&'53255#5#535!#3#3 0VLLIM9I4FDJDAD:aF@C J~d&K'L +"&'53255##333 02_d_ݻN9I4F6tVڑAD:F@C J~d(K'L +"&'53255#'#3733 0-c¹dcI9I4F΅ADF/@, Jf&K'L+3333####=d`f`ם)O6R/@, Jf(K'L+3'3733##'#7#8dcdc6D> 2@/e&K^'L      +!"&5466333'3#"Cw3vcmZdf_WUg^9b<.6MD>C<7G>+'7@4Jg&K_.L$"%$## +326553#"&'#"&546633#"32665940:Yba=MP?ns:~fEF_a/795:7Qj,&%,hfA`6.>K163"/I@FJ~ _/K_.L$#*(#/$/""$%## +326553#"&&'#"&546323&&55"326754&,A74Yd^2>% UKcxv_=KFBCFPA>@J@Ab_+(8.! 2jeee\^dj#.+KPX@(J)I@(J)IYKPX@e_-K_.L@&~e_-K_.LY@&$  +++2326553#"&'&&##532654&#"'66 mu[GT[3;95Xh^[pkaa]abK<;V&-)vcMJV  VJF=;@b`_kKAII<6:"<+&"(L@I&%J~g_/K`.L#! ((+232553#"'&&##532654&#"'66Xl3,1=19iWGGE8AL;7&E&(S"JC19  :4-5¡1+H%-&&F#Db#J@G J!Ie_-K]'L ##+23#5#54&##532654&#"'66qx`JX`ZV[wjceghO@>\(-)zcMJU  XGzD>II<5;#<+&G !$F@C"!Jea_/K'L $$+23#5#54&##532654&#"'66Zn6-5 RVPJMJ;FS@8(L$ *_!JD17  5)J.0I%,&'F)K(PX@ J@ JYK(PX@ ~]&K_.L@*~]&K_.K_.LY@))%'##+32553#"&&5##"&'532667>7Q56lXi[9Y3  '?2# "@8{b`&VGJ5C]0K/J'(p 6@3J~](K`.L##""+%32553#"&5##"'53267!28eX]f .L9 6@;?=_d^CaZKPX@e&K_.L@ e&K'K_.LY@## +326553#"&&55!#3!o5665Xh[9Y2ZZ[@9;@b`&WG.UDhKPX@#~e(K`.L@'~e(K'K`.LY@"# +!5332553#"&55!#X38eW\gX@=`c6= 3@0Je_-K_.L%%&#+!#"&&546632&&#"32665#lOTw;r-"&f45nTL\(r+Yrn\MUI9eA7M"3@0Je_/K_.L$%$#+3#"&54632&&#"3265#P{:\) T/ggYdXM"~Eo`\qRD p0@-~]&K_.L##+#326553#"&&5#58758Yk[:Z5QD@9;@b`&VGQ?0@-~](K`.L"#+#326553#"&5#54825W[iH@=7!3< 0Y  &?3# #N9I4F{J4D]0K1I$&oAD:;!K"PX@JIK(PX@JI@JIYYK"PX@d](K_'LK(PX@#d](K'K_.L@*~d](K'K_.LYY@ !! +"&'53255###"&'53267!3 0X .M9 6ACN9I4Fϩ^B,ADP~&$ n.P!&D C~&$Kp3+.5&DKF~&$Vf3+.,&DV>~&$Wc3+,&DW>~ &$Xa3+.g&DXB~&$Yf3+.s&DY=P~&$' nJo3+.P&D&JJ =~&$Zj3+.L&DZA~&$[i3+.L&D[@~&$\i3+.n&D\D~&$]f3+.q&D]@P~&$'M n3+.P&D&MZ 2aP&( V7P"&H Wa&(KY3+75&HKVa&(QQ3+7&HQ=a0&(VQ3+7),&HVJ&&(WR3+,&HWKa &(XP3+7 g&HXEa&(YN3+7s&HYEaP&(' VJb3+7P&H&JN W(*&,K3+<5&*K(P*&, NP&L =P&2 7P'"&R W=&2K3+7'5&RK^=&2V3+74,&RVU=&2W3+)',&RWU= &2X3+7'g&RXU=&2Y3+7's&RYT=P&2' J3+7P'&R' WJ`=%&Gv#3+7&Hv=%&GC3+7&HC=%&GK3+75&HK^=%&GQ3+7&HQO=P%&G 7Pj&H XZP&8 OP&X PZ&8K3+O5&XK]Z2&Iv 3+O&JvZ2&IC3+O&JCZ2&IK3+O5&JK`Z2&IQ3+O&JQUZP2&I OPk&J OP6&< D&\  3+6&<KI3+5&\K*6&<Q;3+&\Q7f^&Bu@^, 3@0J~L +6673##&&'#56673X42'1441:\9* 3_** B""B^s, A@> J~L    +&&'5356673#&&'93W':]:2443 + _ A""A **@^g$q@ !JK PX@pgL@~gLY@$$  +2#'6654&#"56#&&'#5667.2$) C91441:g"#'? )}"B ** B">^xs%C@@"JWg a L%%! """" +#"&&#"#66323267#&'#56670(-+-/(/+D:03550;s/=.>"@ !/) @"C^jL kJK-PX@~dL@"W`PY@    +#5667#"&'3326741wJFGG5/+&4L 5 + k^xq#wK&PX@" ggc L@- ~ ggW_OY@##!"""" +#"&&#"#66323267#"&'332670(-+-/(/+IGGF5/+&4q.<.<;FD=)'$D@  JKPX@`*L@W`PY#%+4&'3#"'5326l#!>431t9 =+,48 :P/@,Jc]'L +"&'53255#53H 0 Y9I4FPAD !&7zS&Wzg 0) JKPX@'eK _K _ LK)PX@+eK _KK _ L@+e _K]K _ LYY@$"))  +"&'###53533#36632'2654#"S?P?LLXP?dyzpHGVAA . D]BYYB";".Ijdbgci '0vJK PX@&pe]K]L@'~e]K]LY@0.*('%!5! +3#"#&&546332#32654&##32654&##OEH慊FB-I*s[ES[v_JMc} @>Pa?S &F7aj;:;3J<8Ea4U0#JKPX@"]K_K_LK)PX@&]K_KK_L@$e_KK_LYY@##  +"&'##!!36632'2654#"S?P?P?dyzpHGVAA . DJo";".IjdbgciZH2@/eK_L  +"&&5332'2654&##U]n0Zdv4x|PG`\{K 8cA8^9_xMGCE<|NAR-b JK)PX@K_K_L@_K_LY@  +"&5336632'2654#"BnXQ?dy~lHGUBQ ";".Ijdbg`j;7@4J_K_L  +"&'532654&#"'6632;U()R/s|{0Q!$)jAmIN N LZpl]=Z(L@I%  Jg_K_L$" (( +2&&#"&&#"3267#"&&546632546| /$!M0s{{.T)(U;mIOn;:5ZH03N NZpl]@F7"(y@ %&JKPX@ _K_K_L@g_K_LY@#! (( +"&&54663254632&&#"&&#"3267,Hn?ArH!5> /@ML+DA :z_c|:[AE I0|I ag N [K PX@p]K]L@~]K]LY@5! +3#"#&&546332#'3 4&##OEHkVŰma"u} @>PrM3 9@6e]K]L    +!"&5466335!5!'3#"?5}k\eRfdXh^8b7$ JKPX@"]K_K_LK)PX@&]K_KK_L@$e_KK_LYY@ $$ +"&546323&&55!5!#'#'26554&#"dxyd>OG P1UEBYGGG .! 3JH"0I]^dkq_`j6 &"\ 3+< /@,e]K]L  +35!5!5!5!5!<5#ONO6;6&*K@H$JIe_K_L ** +2&&#"33#"3267#"&&54675&&546:Jv)+(T@DBHR5];LZ  UIMd>@;Je]K_L  +"&'53265!!!!-   "KL#/OO~SJ=Z-[@X*  Jge_K_L)'! -- +2&&#"&&#"32675#53#"&&546632546 /"&_37v`/B:vKoOWuHA6ZH05NUI PYqo[@F:"2@/ JK_L"" +"&546736673'254&'6>(^_!">6"L9,t6_,M##O,sAq%8MN9H#%EUU#ĵJKPX@K_K_LKPX@!K_KK_LK)PX@%KK_KK_L@%K_K]K_LYYY@  ## +"&554&#"#33663232653jl58R=XXT0[\~A=Xk ]gA@e^(#)*]gEPDxcZR+@( JK_L  +"&&533267,E(Y%(/ 7 IA-00J "07@4 JfKL +3#!57#535'5*TZZTTZZT4N44N4akK(PX@ J@ JYK PX@_KLK PX@_KLK(PX@_KL@K_KLYYY@  +2&&#"##36677>)  $jOZZA|'$FkVM#J$ U ^@JKPX@_KKL@gKLY@ +2&&#"3>773#'#4#  gj=W I4 5q HK)PX@eKL@e]LY@  +3#5333#UFFXFFbBTB,KPX@ '  J@ '  JYKPX@_K_LKPX@_KK_L@gK_LYY@ ,,&%' +#''7&&#"5663273267#"&''.'#jc" #9Amf %+I z@ ?G,.!? 6A%,;9#P'Z#] JKPX@K`L@KK`LY@ ## +"&533265332653#'##"'#e`Z:?YLZ:A\GZGd5+i gsFFd^FFnh6R..d319@6JKK_L  +"&'5326533.53##-   h}TiDL#/@K!6Q#h7SJU"=b=*TJKPX@_K_L@_KK_LY@ $%#$&# +#"&&5466326632#4&#"32654&#"GgjEEjIp'e8daZ:?f%5jqqiipqkfo\\om\/,.-gsFF=\7"&3@0 J_K_KL$%"#%" +#"&&546326632#4#"32654&#"mCj=mj?L*PPW\@#EKKFFKLD A}YH%#^gI,@__oo__ll z"bK PX@!pe]KL@"~e]KLY@" %5! +3#"#&&546332##32654&##OEH׌5}kRHfdY^[} @>nd;g@cBOEDU0#1@JKPX@&_K_K_KL@$g_K_KLY@%$,*$1%1! ## +2&&#"36632#"&'##4"326654&$ NAcyyd>QXRDAX0@G IP4#0. 4a\^ck5^<\na_;@8JeeKL! +##33232654&##ZZk*A$\kWPTXfd'def9L. sECF;/)7@4'&J_K_L$" )) +23267#"&54667>54&#"'66Cg:][AN#QP9k$"fVj_8J5'0$/9M-"(7@4&%J_K_L#! (( +23267#"54667>54&#"'66ah(J44:OS#|@ JKPX@!_K]K_L@g]K_LY@ ## +2&&#"3#3267#"&&5#57546* .!7!:@@4=J@^W9X3 P 0p@ JKPX@ e_K]L@ge]LY@  +23#!!5#536654&#"'66]ldv(>2/G%/'e`U*O,FFIF.K*46" ;#1#A@>Je]K_L  +"&'532654&&###5!!32:g-/n2a`/P2|^*KwE? RRL2@ PP3bGCi;!A@>Je]K_L  +"&'532654&##5#5!#32:^"]7Z*#r{D\" C=NPU"_ JKPX@_KKL@K_KKLY@  +2#3366"6654&K<^6^kXH J+L@G"2dI_VI#0J\^kDS0K)PX@ KL@ ]LY@  +33N&A`K)PX@ ee  KL@ ee  ]LY@ +3#3###535#535)NH`H H`HHa&''=K!3+a&'']K7&G']gKaB&/- a&/M U&OMaB&1-a&1MU&QMj~&$Km3+.&DKHS&,K3+*&*K=&2K3+7'&RK^Z&8K3+O&XKdZ&8n3+OD&X5Z&8n3+Og&X5Z#&8n3+Oq&X5Z&8n3+Og&X5~&$>3+.D&D~&$>.E&D5W&L03+.-&L=(X@U  &Je e_K_ L%$#"!  (( +"&&546632&&#"32675#535#533#yKWuN9gEF~SSa&1C3+U&QC~&$ d3+.&D ?~&$ >3+.&D Q&( W3+7&H Ca&( 13+7&H 1&, 3+&* E&, 3+&* =&2 3+7'&R U=&2 3+7'&R /W_&5 ]3+&U a_&5 73+T&U Z&8 3+O&X [Z&8 n3+O&X 5&L ) @" G_L +5>54&''>54&#"'6632'qW&=5#L(_v7F>;`-+9yB8gA?4";%cմV54&#"'6632-(C%X_$92,M%.^16Y5/+,?hO"mU3;  B/6".1@!IsZNZn_ZGFR}C]]ygY\.7U*7CHKPX@A (JK(PX@A (J@A (JYYKPX@+  gK_K  _LK(PX@7  gK_K  _K  _LK)PX@3  gK_K _K _L@3  g_K _K _LYYY@98,+?=8C9C31+7,7$%$( +'67&&'##"&546323&&55366#"&'%26554&#"%2654&#"3Q SPdyyd>OX$a2=AZh'UEBYGGG8.'8 iR;  43.! 35>.;-4J9]^dkq_`j,':e+<@9JgK_L! '% +!+  +"&&5467&&553326553'2654&#"MN}HNG:7ZINOIZ8;DSF}S_XY_^WW 9lMRccEXXDXXDXXFbcQMl9NWMMTTMMW2"*cJK)PX@gK_L@g_LY@ &$* *  +"&&5467&&553326553'2654&#"(Go@D>00X=AA=X10OXQ?dyp8d=IKBYGGHLGUBH .! :"";".}AOXQ?dyp8dLGUBH3IKBYGGH".! :"";".}A 81 "#F4+(:DBn LA,(H-@* J_KL +2#6654&#"'66gv^hZXi?C#W!#efYK1BnF4?H "-@* J_KL  +2#56654#"'66gj$RFXXb{#M!#["fY-^V bnFyBT*I@F Je e]K] L*)('&$ ! +35#5332#32654&##32654&##3#aRR̅FB-I*s[ES[v_JMcNPa?S &F7aj;:;3J<8EVN 5@2 eK_L$ +533!33##"&5532655! PZsYQQ<|^Z]^aWbNNfJwEwdgW`gQf_haKPX@.o   eK ]K  ]LK)PX@-   eK ]K  ]L@-   e ]K  ]LYY@ +!##7#!733#3#337#37#Ah A 1E8kAw8"AcKK..ONM70&+/@*. JK)PX@-  fK _ K_L@-  f _ K_LY@',,''! ,/,/'+'+$# &!&  +273#3267#"'#7&&5466"37&4&'7$KCR7=< *3O*)P74,ICS18;kF?Ip5 w,)/"qN5 M!uRX~DHQH*CFW0B:@7JecL  +"&'532665#5333#$$-RRZQQfL1.6NBNgb #@ JK PX@%e_KK_ LK PX@%e_KK_ LK-PX@%e_KK_ L@#geK_ LYYY@  # #$" +4632#"&"&'53265#53533#N8&   *KKXKKHG#1KGGKU= #2@ JKPX@"_K_K_L@&K_K_K_LY@%$+)$2%2 ## +23733267#"&55467##"&&5466"3266554&&kIrG   CKpP_EE`bllcX]$$^8.\/#LJSg$.8\on[N6_??_67u""/@ JKPX@"_K_K_L@&K_K_K_LY@$#*(#/$/ "" +23733267#"&&55467##"&546"326754&?P F $6 Q@ay{nHFFJRFD"0#I;%C IA>0"0Iq__k[^fi _A@>Je ]KL  +2####53#32654&&*A$iZWWfkWPTef9L. ''LWNECF; "{KPX@  JH@  JYKPX@e_KL@ eK_KLY@%$ +##5#535336632&&#"+~XKKH S8" 8X ?GGb,@QPC65@2J fKL +##'#53'33737#,f~Ze;EbCDaFMJNNߑ&9@6J fK_L#"%# +33733##"&'532677#5336677#^C?_C9TXN$ .8t[>GLZF4+G"GQ)89)HQ"D1 3+7"g JKPX@_K_L@!K_KK_LY@  +"&54632373#'#'26554&#"dxyd>OFG P1UEBYGGG .!EH"0I]^dkq_`jU0"!g 3+U0 +@JKPX@"_K_K_LKPX@&_K_KK_L@$g_KK_LYY@"!(&!+"+  +2&&#"36632#"&'##4"32654% P?dyzc?P?VAAXHG I8";".. Dqbgfjjd!"7@4  J_K_L  +2#"&'532654&#"'66Fkdyyd>OX 'UEBYGGGIA?3 !..! 3;%C /]^dkq_`j7u -@ JKPX@"_K_K_LKPX@&_K_KK_L@$g_KK_LYY@"!)'!-"-  +"&546323&&55432&&#"#'#'26554&#"dxyd>Oy$ G P1UEBYGGG .! 3O IH"0I]^dkq_`j3"GH4@3">@;Je_K_L  +2#"&&55!&&#"566!326MtA;kGDd5oYP3O*)P>C?I">zZX~DKLM*ES7"QA45 4)-J,Jhehd/0,%H!0".=@:JeK_L  +"&'53265#53533#&   *KKXKKHG#1KGGKU6u-:@'JKPX@+_K _K_K_L@)g _K_K_LY@/.53.:/:%# -- +2&&#"#"'5326554665##"&546323&&554"326554&4# u{vKOwEO6phuth4VDIIFQJL Ist"Q*QFQ()4HkcciWam`7"J7"F@CJe_K_L  +2&&#"32675#53#"&&5466Cm> F ML$3s1_:Hn?Hy"$LagG:z_c|:%2@/  JK_L%% +"&546733>773'2654&'4?&^f" f^"?4G52\3 U 667;\*4HIBA"0<9@6) J_K_L86#!00 +2&&#"#"&5467'&&'&56632366776632654&   y$ ?44?""  *=   =,"E1B+3==4+D.C&T),V "+-Q Kj 3+U b@JKPX@_K_KL@g_KLY@ "(%" +3432&&#"36632#4#"Uz$ Y4acWxZCq I^(#)*]gWe^U+@ JKPX@%_K_KK_L@#g_KK_LY@)(%#++ +2&&#"36632#"&'532654#"#4$ Y4acy# xZCX I^(#)*]g?I e^q  K PX@! e_KKLK PX@! e_KKLK-PX@! e_KKL@g eKLYYY@      +2#"&546##5#5353KXKKX^GGRH$ &@# JKL  +#57'5PPPP4s444uh@  JK)PX@ggKL@gg]LY@"#"# +3&&#"#6632332673#"' 39/ X 28/r;E<:FTi JK)PX@g gKL@g g]LY@%! +3#"&54663233#354&#"*>6/'  Xhh{#);.0 yHq  U=I@ JK)PX@K_L@_LY@   +"&&533267,E'W$)& (IAA00C Uo@JK)PX@(gK]KK_L@(g]K]K_LY@  +"&'532654&##57!#3!f;^ !b:M`o[;XXqAxPYMTK=2@omGm=QRP 3+QR$4@1 JK`KL$$""$' +5467##"'##"&533265332653U0~&]4[ZWmNCWnQ>X3 *)Z.,^g]ZV(d^UV",z@)#  JKPX@_ KK_L@#K_ KK_LY@(&"!  ,, +2#"&'532654#"#4#"#336632366[Zy$ mNCWnQ>XG U0~&\"^g?I ZVYd^I*)Z.," m@JKPX@_KK_L@ K_KK_LY@    +2#4#"#"&'532653366W`bWxYD$=#%  G \"^gWd^AI C%;`I*)U" a@JKPX@_KK_L@K_KK_LY@ $%%" +3267#"&&54#"#336632 &#<$xYDXG \3`bH;%C IAd^I*)^gU#@KL +33.53#UlSmP00 6 357'"c7,"$KPX@ JKPX@  J@  JYYKPX@#e _ K _LKPX@6e _ K ]K]K _L@3e _ K]K]K _LYY@ $$  +25!!3#!!5#"&&546"32654&0^>` P1Go@rEWKRQLL"A7III6!A}YJl__oo__l8"'C@@ J~_K`L#!''  +2#"'##"&5466"32655332654&kMb]l" m]bKpy<11/T2-2<|"NbkZZkaOIrRTJ8>DTRr6HU 3+HKPX@ J@ JYKPX@K_LK)PX@KK_L@]K_LYY@  +"&'7326653#'#N# *G+XH R Q-Q6b,@#B@? !JK_K_L ## +"&&55467##"&'73266533267m!9#R8# *G+X (IA\3 ,@Q-Q6;%C U"fKPX@ J@ JYKPX@_KL@K_KLY@  +2&&#"#3366O" )H+XH S"Q-Q6b,@U" |KPX@J@JYKPX@_K_L@K_K_LY@   +2&&#"3267#"&&53366O" )H+#) !,E'H S"Q-Q600C IAab,@RH"+@(J_KL  +2&&#"#4660 &##W(H" K ,0{AI"+@( J_KL  +2#4&#"'66h0H(W##& 0"IAj0, K U3@0 Je]KL! +332#'#32654&##UVh$9 f~>E4>RL0>$,/%1UGM@ 3+3"7B@?)*  J_K_K_L%,&%$" +%#"'3267#"&&5532654&&'.54632&&#"tb."$( !,E' [/C<954J(oZ1U%"J'69=33H&NPD00C IA+$ (8,DJF#(9X@JKPX@_K_L@g_LY@ +2&&#"#"&'53265466%  $=#%  $= C%;bAI C%;BH%w@JKPX@ e_K_L@ge_LY@!  %% +"&'53265#5346632&&#"3#)%  KK$=#%  KK$= C%;@GBH C%;GAI"7@4  J_K_L  +"&&54&#"566323267#=$  #!8!  %IA1(C D=3;%C (u@ JKPX@!g_K _L@gg _LY@$"((  +"&5463346632&&#"3#'2655#"!@ODM2$=#%  KK'>- ,(B47CVBH C%;HBIH%,Y"Wi 3+S@@=J]K_L  +267#"&&5#57733#* 4*G,LM#4/C HA*#r{D1/ `l JKPX@  eK _L@#  eKK _LY@$ +75353!533##'##"&553265! EYXKKH \4abYwYEGGG*']fD>c[? 5@2 J]K_L    +"&&5467#5332654&&'53#-Go@630HKRQL"8j =qNJl'IEuVPcdP3\D EIUwQ"qKPX@ J@ JIYKPX@_K_L@K_K_LY@  +2#"&53326554&#"566.D%otvmXCHHC& &"HAyyu}0aKM_7% KY 3+ Z 3+\ 3+#@ JKL +#537Xd;'!H@E J]K]K_L  +"&&55!5!5!!3267#:" p# &IAI:DBn;%C '";@8 JGg]K]L$"$" +'667#5!5!36632##732654&#"C  pS)X>4BJ[a3E- 2W:DBnQN>*7D&j,'2b@_*%"J I#Ggg]K _L)(.,(2)2'' +"&&546326654&##57!5!&''27&&#".Y:XN;o5o[;DpB &9$!&nDa9/W-/&>?26D%$  TK=J@5aI5)6( "&I4# $ I@  JKPX@_KL@gLY@   +2#6654#"'66gj$RFXXb{#M!#[fY-^U!kmGyBGa@ K@  JK)PX@K`L@`LY@   +"&'73254&'35[#!M#{bXXFR$j ByFnp V^-Yf7"7@4  J_K_L  +"&54>32&&#"3267,|y'E[4(M@2G%#E1+DAr[' I ?su; N=&2yU-!"%?@< Jg_K_L" %% +2#"&546675&&546"33#"32654xr!6 .7sdSE*S>\U"[C(5  91CJJK-%HZ2(fh7Q+@(  JKPX@(e_K_K_L@&ge_K_LY@'% ++ +2&&#"&&#"32675#53#"&&546632546 / F ML$3s1_:Hn?HyK5*6 I0LagG:z_c|: ^AEU( 'K PX@'g _KK _ LK PX@'g _KK _ LK-PX@'g _KK _ L@% ggK _ LYYY@! #!''    +"&54632"&5463333#'2655#"ndyyd>O#9"' UEBYGGG3 !..! 34BH C%;/]^dkq_`j e@ JKPX@e_KL@geLY@  +23##5#5356654#"'66gj#O@llX[[Q_{#M!#[fY-^U!PII~mGyBe@  JKPX@e_KL@geLY@  +2&&#"3##5#535.5465[#!M#{_Q[[Xll@O#jByGm~IIP!U^-Yf7'*2KPX@  (JK-PX@  (J@ (JYYKPX@ K_K ` LK)PX@5K_K]K ^K ` LK-PX@5_K]K ^K ` L@0_K]K^K _ LYYY@*)#!'' +"&546323&&553!!!'#'26554&#"!dxyd>OX#2 P1UEBYGGG9 .! 3BnDH"0I]^dkq_`j72?KPX@*!  JKPX@*!   J@*!   JYYKPX@1  gK _K  _K_ LKPX@;  gK _K_K  _K_ LK)PX@=  gK _K]KK  _K_ L@=  g _K]K]K  _K_ LYYY@#43;93?4?,+)('& 22 +"&'532654&##57!#'##"&546323&&553!26554&#";^ !b:M`o[;G P?dxyd>OXDpBAx'UEBYGGGPYMTK=2H"0.! 3@5aIGm=/]^dkq_`j7)69CiKPX@  7JGK-PX@  7JG@   7JGYYKPX@)  gK  _K ^LK)PX@?  gK  _K  ]K ^K `LK-PX@?  g  _K  ]K ^K `L@9  g _K ]K ^K _LYYY@+*B@<:9820*6+6$"$$ +'667#'##"&546323&&553!36632##%26554&#"!32654&#"C  P?dxyd>OXS)X>4BJ[a;UEBYGGG9E- 2WH"0.! 3BnQN>*7D&e]^dkq_`jp,$8K(PX@ J@ JYKPX@_K ]LK(PX@*_K]K ]L@'_K]K ]LYY@'%54%8'8 $# +3"&&5#5773!6632&&#"#'32654&&'.5467#*G,LM#4 *1U%"J'69<43H&tbC<954J( /HA.*#r{F#(9+NFH $ (8, 1/-6@&'1JKPX@3~_K ]K _K_L@1~g ]K _K_LY@/.32.6/6%$%%# +#"&'532655#"&&5#57733546632&&#"267#$<$& 1*G,LM#4$<$& (/IAI C%;LHA8*#r{>BH C%;1/46A@' @4 JKPX@)  g_K _ L@4  g_K]K _ LY@#87><7A8A20+)#! 66 +"&&5#57733#3267&546632&&#"6632#"&'%2654&#"*G,LM#4,1M$ArH(M@$U7HQ5Q*>c!*aL)5"*)E!( HA8*#r{D1/)6Pc|: I %%D62?') 0I$ "< 5KPX@!"  +J@!"   +JYKPX@)_K _  KK_ LKPX@4_K _ K ] KK_ L@2 g _ K ] KK_ LYY@0.*)&$ 55 +"&'532654#"####5754632&&#"336632}" 'wYDXX^^[S6*,+X4bbFG#1c^,)h[ E ;?#I*)]gRKUUi,KPX@J@JYKPX@K_K_LK)PX@ K_KK_L@ _K]K_LYY@  ,, +"&'#332654&&'.54632&&#"s;`+XXdgVF:44J(oZ1T&"J'69<43H&  z5+$ (8,DJF#(9+NPU4 ^@  JK)PX@K]K^L@]K^LY@  +33!!%!UX#yBnD; N@K J~ | KL    +#'#3737#'#3737cKQSIbFBTFPFEcKQSIbFBTFPFPPU0@-~e]KL +!#5##!#5##UXXXX闗闗""~KPX@ J@ JYKPX@_K_KL@ K_K_KLY@ "" +232653#547##"&554&#"5660#;#xZCXXZ4bb &"<1ځe^(#)*]g#E"/KPX@-,J@-,JYKPX@!_K_K_L@%K_K_K_LY@*(#! // +2326533267#"&&5547##"&554&#"5660#;#xZCX $6 Z4bb &"<1ځe^;%C IAH(#)*]g#E7]GK)&f 3+7]G3)&f 3+vGM)&f 3+7gGU)&f 3+ aGF)&f 3+ aGH)&f 3+7aaGN)&f 3+ aGZ)&f 3+LaG\)&f 3+  [  ? *dD@gW_O +D2#52654#1<<1 8822727? *dD@gW_O +D"&5463"31<<1 8?821827 8dD@-  JW_O%% +D5654&#"'6632Py%&5<&EH:BTH'4D2,D4G!@ 3+! 3+"  'dD@Jt +D73#'mm'TT"뼼 " / /3+(Tx P(^v(^C(4x P 3+(mQL 3+(4 (4 H,dD@!JU]M +D'37YYY苋HdDt +D'3Y( 3+( 3+~  3+~  3+  3+K dD@U]M +D#53<(; JaG0)&f 3+7pGO)&f 3+!gGV)&f 3+ LaG[)&f 3+ Gb)&f 3+NT,dD@!U]M +D!#5!nBPNT0dD@%Ue]M +D!#5353BBPNT0dD@%Ue]M +D!#533BFB(PNT0dD@%Ue]M +D!5#533BBPNT&dD@U^N +D!!533TBBnNT&dD@U^N +D33!NBBNT*dD@Ue]M +D33##NBBB(9zK ۰3+(W*5 53+ [ (v'dD@Jt +D'373OXYNކ(v'dD@Jt +D73#'(1OXY܄(#0+'57#k1kE>?(#0+57'5(E>?Ek1(C 3+(GR@ 3+(R 3+(CQ 3+HҰ3+(&dD@U]M +D3##(q55(-dD@"U]M +D#5#55q5( ,dD@!U^N +D333(5q 5( &dD@U^N +D3#5353Φq55(0IdDK PX@nU^N@U^NY +D!53!53B8M9Хcc(0FdDK PX@nU^N@U^NY +D!53!B8Хc(K 1dD@&JH GU]M +D'57!!#O1;D54&#"'663233267  0DJ Z!5# &NU X!1( 9I4gppD%ew?TEEpvC ^%ew?XAAD=T JK1PX@_@K]9L@a_@LY@ +2#5.5466"32654&hI?{ZZ]z!WLKFM=WD % 5eSe> I niA 6C   <92 &H>72 `&I0,=@:) *J_BK_=L'%,,+"&546756654#"'6632%3267KB ed+ (<=G^t  # E88&L7#?+ E ;.I1I:")E O@  JK1PX@_@K9L@_@LY@ %.+!6654''7&''7&#"'6632q'(4H5V*'aGLH$!pCC+D$F EJ@  H=L+6654&''7&&''7&&''"&+ 54&#"'663233267#"&5467I!5# &NU X!1( KR %ew?TEEpvC ^%ew?XAEpvD7&"$3F@C Jg_CK_9K=L&%/-%3&3$$ +2#"&&'#32#654&&#"&&546"32654&>Di;m'5+"<.CEM ')Oe0L\(J4OEE"@|Z FJ  BI #hegf7"FM=b7""a*U0=Y&a*P JK1PX@~8K9L@~]8LY@ +3333#467###azyYJ66j#!l7RUX JK1PX@~;K9K=L@~];K=LY@ +33#467#'UhcTH R34&"&J@G$Je_CK _9K =L" &&%# +5#534632#"&'#3#2654&#"OKKnDi;m)LOEEMLTFi@|Z@)FT/hegeƢ;h=Y&&y;&hyk=V47"T : Z ,@) JfKL  +33#'#73'&' M[A?[9 桡 8@5ee ]K]L +!!5##!#3#3%35#ԩP]|MHG32",7>@"'!  JK"PX@#  e_K _L@( U  e_K _LY@=;9864$#%"$%#" +3267#"&'#"&&55!&&#"5663266324&#"766#3262x|Z=3(M!#d1>QT6A^3WOJ1M&(M2>#[MIa[3*?UK^H9=:CPW"A4B)-).yFDBF:E+DYE;3+L&#.(';7@4  J_K_L  +"3267#"&546632&&FQ]VX"E#"D.>xV+S#"Bm^^m H Q|EE V@]K]L!$!" +##324&##32~\d\M>d^v$ ?@<e ]K]L     +2##5#535#3#3254&}88H9dHGHd^V )@&e]K]L +!!!#3#3AHG!"(J@G"Jg_K_L (( +"'732654&##53254&#"56632gT(C,;?SE:HS<7]"^:vo!6 .7m %F&&-%HZ2)O[C(5  91CJV7)@&cKL  +#2#"&546X+2 +@(JK`L  +"&'532653t $'XR G -xPJV&@# JKL +3366773#'VYgg+#% ,@) JK^L  +35'7373V#AY`$:&7R;@ ;3+HEF#@ 3+Z$:@ :3+4|" 3+9*9@6JgK_L &$* *#) +#"&&5467&&55332655"32654&#)/8xd>b950%%Y1562hA==AA>>H1EJ8X`+R;9IH.HH.<<.H955<<559; ? $@!_L  +2#4&#"#466>}]OUVP]9s }_ll_S{E;? !@_L"# +#"&&533265?;sTWs8]PUUP S|EE|S_nn_V 2@/g]KL       +2####32654&ne*bT3Y:+HE=TM-N1G-5./8@5Je]KL' +37.54633#5#35#"0ijXXDG;>< $<-IP(--1;@8JgK^L  +!"&54667'3353'35#"ji0fXXGD@<>PI-<$ G1--(@]KL +!##5!#YHHQ!@K_L#$ +#"&533265/bJjmY@AC=8Z4m[W=BH7Y&/HQ&H@ H3++@ ܰ3+(JP(@ 3+FY7336673#.'#RC  VWT  DQ]T  W,X37."PX..:. /:']!A@>  J~]K_L$%' +#"&'532654&##57!5fWov:^"]77!Y<8   :6tj&WG H,BqNG$)&f 3+G)&f 3+?G%)&f 3+ &lK%PX@# e]K]L@!e e]LY@&%!%! +535323###5732654&##32654&# 2VZ'QAVK;U<,6;L]>02@-/;2- ';?-$"#,$")?G')&f 3+?BG()&f 3+'*Gp)&f 3+(G*)&f 3+?G+)&f 3+G,)&f 3+vG-)&f 3+?G.)&f 3+?DG/)&f 3+?G0)&f 3+?G1)&f 3+?=JK%PX@KL@]LY@ +333#5467#?7D6FbT!?(G2)&f 3+&G)&f 3+?hG3)&f 3+?G5)&f 3+bG7)&f 3+:G8)&f 3+TG:)&f 3+8fGD)&f 3+5OgG )&f 3+$XgG!)&f 3+!gG)&f 3+7lGE)&f 3+$XGG)&f 3+$MgGH)&f 3+!KgG))&f 3+$gG*)&f 3+!gG)&f 3+$XgGJ)&f 3+8{aG)&f 3+7UGN)&f 3+7+gGP)&f 3+7^gG )&f 3+$fgGR)&f 3+gG$)&f 3+&veG)&f 3+&vG)&f 3+7lgGS)&f 3+ GW)&f 3+3ZaGX)&f 3+;|JG )&f 3+5(aG<)&f 3+JaGY)&f 3+ >eG)&f 3+7}G~)&f 3+MaG)&f 3+#fG)&f 3+$gG)&f 3+bbG)&f 3+3vZFL)&f 3+7FU)&f 3+3ZFX)&f 3+JFY)&f 3+7}kF~)&f 3+MF)&f 3+3fF)&f 3+$F)&f 3+bF)&f 3+Qo"'.y@ JKPX@"   e]K_L@&   eK_K_LY@(((.(.&##$%" +%!3267#"&'#"&53326536632'&&#"oYP3O*)P7Bc#YGjmXAACC?I[_M.4)6m[W=BH7Y8%O 32) X 21* G P1UEBYGGG .! 3S;E;k;EH"0I]^dkq_`j0@# /JKPX@. g  g_K]K  L@,g g  g]K  LY@00.,*)#%%"" +3&#"#66325#5754632&&#"3#32673#"'m 32) ^^[S6*,+ 21* ;E)h[ E ;?#D;E"-6@@  =. )& JKPX@) g  g  _K L@- g  gK  _K LY@777@7@;95420--$$ +35#6675336632366326673#5"&'#5&&'54#"54#"U30-G U0~&\5[Z20/W=AW@=nFA:mNC=.; I*)Z.,^gM/<  -,MG +NZVy""+@)& JKPX@#~|_KL@'~|K_KLY@$##+$+ "" +26673#5.'#5#66753366"54W`b21+W.`^)X35*G \&NGAE"^gP7; 8: I*)JMI%I0".<@ ! JKPX@/g g _K  _K  L@3g gK _K  _K  LY@0/75/<0<..($$"" +5&#"#6632336632#"&'#32673#"&'26654&#"U 32) H NAcyyd>Q 21* 0@GJRDAy;EHI#0. 4K;EI/5^<\n\^ck",KPX@ +JH@ +JYKPX@$g g_K  L@(g gK_K  LY@,,"%%$" +35&#"#66325336632&&#"32673#"'U 32) H S8" )H+ 21* ;Eb,@Q-Q6!;EH"*K@H )Jgg_K L**"%%%"# +35&&#"#6632546632&&#"32673#"'R 32) (H00 &## 21* ;ENAI K ,0|;E"8g@d !4J~|||_K_L10.-%#88 +"&'532654&&'&&#"#667&54632&&#"26738Q [/C<94 D3&$oZ1U%"J'69QXKKH N1JE#F>DGC"qrF. 4FI#0JLMGRghRZ` JA@> eK _ L  +"&55#5353!533#'2655!(jmGGYXGG/bGC=@m[BFFD8Z4GH7DD=B S$/S@P JI  e]K _ L.+)'  $$ +"&&545#53667#53!&&'53#3#%326545!-Go@-6 0%$=&=#J6,KRQL =qNF-GIEK85PEI;UFwPcdPU:0%1KPX@!J@!JIYKPX@$cK _K_LK)PX@(cK _KK_L@(c _K]K_LYY@'&.,&1'1%%#%(' +36632#"&'53255#"&'##"32654P?dy%"9< 0!&?P?VAAXHG";".Km#rADI4F . Dbgcijd7:>$1KPX@ !J@ !JYKPX@%cK_K _ LK)PX@0~cK_KK _ L@0~c_K]K _ LYY@&%-+%1&1 $$ +"&546323&&5533#"&'53255#'#'26554&#"dxyd>OX,9< 0$ P1UEBYGGG .! 3QADI4FH"0I]^dkq_`j:&@JKPX@+~ c_K]KL@)~g c]KLY@#"!  && +"&'53255##5754632&&#"3#3| 05^^[S6*,+,9I4F)h[ E ;?#DuAD7"/<@ ' JKPX@2eg  _ K _K_L@6egK  _ K _K_LY@!10750<1<+)! // +23733#"&'53255##"'532655467##"&546"326554&5U F9< 0u{vKOwEO6phuusCJHGQJL"()GcADI4w>st"Q*QF - QJkcciWam`U:"x@ JK)PX@!~cKKL@'~c]KKLY@""%# +3>7733#"&'53255#'# gٲ:9< 0=Ws4 ADI4F5(:]@  JK)PX@~cKL@~c]LY@ %# +3#"&'53255#,9< 05PADI4FU:"0@$ JKPX@%  ~ c_ KL@)  ~ cK_ KLY@-,)'#! 00 +"&'53255#4#"#4#"#336632366323  04mNCWnQ>XG U0~&\5[Z,9I4FYZVYd^I*)Z.,^gADU:E""}@JKPX@"~c_KL@&~cK_KLY@ "" +"&'53255#4#"#3366323 04xYDXG \3`b,9I4FWd^I*)^gADU0"%3@" JKPX@%g _K_KL@)gK _K_KLY@'&.,&3'3!  %% +2#"&'53255#"&'##3366"326654&Tcy%"9< 0!&>QXH N1RDAX0@G"Kn#rADI4F . 4I#0J\^ck5^<\n(:""KPX@J@JYKPX@!~c_KL@%~cK_KLY@ "" +2&&#"3#"&'53255#3366O" )H+,9< 05H S"Q-Q6։ADI4Fb,@3:":L@I*)#Jc_K_L.,'%!:: +2&&#"#"&'53255#"&'532654&&'.5461U%"J'69=33H&9< 0(8Q [/C<954J(o"F#(9+&:aADI4DP+$ (8,DJ.@$#JKPX@&eg_K_L@$geg_LY@(&! .. +2&&#"3#"&'53255##"&'53265466%  9< 0$=#%  $= C%;&ADI4{~AI C%;BH:=@:JcK]L  +"&'53255#33>733a 0^rr^9I4F6235<.AD:@@=  J~cKL%# +3#"&'53255#'#37,9< 0 c¹dɊADI4F':@@=  Jc]K]L%# +!#"&'53255!5!5#9< 0 BnADI4F:D.:n!+6KPX@ ()J@ ()JYKPX@(  e d_K _LKPX@/  ~  e d_K _L@3  ~  e d_KK _LYY@-,20,6-6&$!  ++ +"&55#'##"&5467754&#"'6632332672655.2?#NCI`~[:5*L!#`4b^,  #C[OdM7=J?L,*MRPW C4BV^܇#EKN083-*7:""/KPX@J@JYKPX@!d _ K_L@0~dK _ KK_LY@$#*(#/$/ "" +237333267#"&55#'##"&546"326554&>OF,  #2?$ P?dxypGGGHUEB".!E1#E=J?H"0Iq_`j]^dk7u0=@ -.JKPX@+_K_K _K_L@)g_K _K_LY@21971=2=+)$" 00 +"&&55467##"&546323&&55432&&#"326726554&#"/6 O>dyyd>Oy$  $UEBYGGGIA?3 !..! 3O IA;%C /]^dkq_`j7:K"$+V@S#Jec _K_L&%)(%+&+  $$ +"&&546632!32673267#"&55"!&&9MtA;kGDd5YP3O*  #1@,K?I> >zZX~D QHDU+:!"5]@Z +23Jec_K_L0.)'$"!55 +"&55#"&546675&&54632&&#"33#"326732671@,8sn!6 -7s[:S(!!E/ySF8IR<7V!  #=J> YC(3 ;1DJFL,&H\1(#E!:"5]@Z!+23Jec_K_L0.*( 55 +"&5532654##532654&#"'632#"'32672?"]7=Jivte\ov5  #=J.42)AIGSFKeA#E7lgG")&f 3+$#gGF)&f 3+>gG%)&f 3+$fG)&f 3+!gG&)&f 3+ GI)&f 3+aG,)&f 3+$XgG.)&f 3+5ZaG2)&f 3+G5)&f 3+5aG6)&f 3+aG7)&f 3+aGg)&f 3+Gj)&f 3+7G:)&f 3+Gq)&f 3+7aGl)&f 3+7+gG>)&f 3+5(aG=)&f 3+]gG?)&f 3+7gG@)&f 3+7daGA)&f 3+$fgGB)&f 3+#GE)&f 3+!gGO)&f 3+GP)&f 3+ G)&f 3+aGV)&f 3+vaGW)&f 3+5OaG)&f 3+5\gGX)&f 3+JaGY)&f 3+aG])&f 3+baG])&f 3+ZaG^)&f 3+ .aG_)&f 3+$_G)&f 3+aT&%N3+U0&ENaPT&% eUP0&E lamT&%L 3+Ul0&EL 3+=Y&&'zv3+7&F'zva&'N3+7&GNaP&' 7P&G Nam&'L 3+7m&GLt 3+a'7@4J]K]K_L!,!6$" +#"'532654&'7"##324&##3 JJ  $&5&) kV$3ua"057VPr;(Ώ7*7@ ) JKPX@'K_K _K_LK)PX@+K_KK _K_L@+_K]K _K_LYY@,+31+7,7$"** +"&546323&&553#'##"'532654&'7726554&#"dxyd>OXG 0!$3KI  $&5&&UEBYGGG .! 3H& 5(&057LI]^dkq_`ja8&' V78&G $a+&(73+7q&Ha+&(53+7q&Ha8&( ,78"&H -aC&(i7G"&HQ= 3+a&('zMr3+7&H&M^za&)N3+&IN3+=W&*L3+7&JLla&+N3+Q&KN)3+aP&+ UP&K `a&+jQ3+&Kj`3+%&+z&Kz aG&+ sUG&K 5Ha&, H8&LQ 3+=&,3+g&*ak&.v3+E &Nv3+aPk&. tUP &N 5amk&. JUe &NLj 3+aP&/ VLP&O PW&/' VL3+P&O' L3+as&/Lo 3+p&OL 3+a8&/ ,<,&OJ ް3+a*&0Nm3+UV&PNaP*&0 UPV"&P a&1N#3+U&QNaP&1 UP"&Q _ae&1L 3+Ua"&QL} 3+a8&1 |U8"&Q 5=#&23+7'q&R/=&23+7'R&R/=+&2|3+7'q&R+=+&23+7'q&R(a*&3v3+U0&Sva*&3N3+U0&SNa_&5N3+U&UNaP_&5 rIP"&U aP_W&5'Lz r3+IP&U&L3 ag_&5L  3+o"&UL 3+3&6N3+3&VN3P&6 +3P"&V 3&63+3&V3&63+3R&V3P&6'N +3+3P&V'N  !&7N3+SY&WN>xx3+ P!&7 @PS&W  q!&7LY 3+mk&W 8!&7 3~&WJ հ3+Z&8jL3+O&XjZ&8Q3+O&XQUZ8&8 lO5&XJf װ3+Z#&8n3+Oq&X5Z&8n3+OR&X5X&9QO3+&YQPX&9 UP&Y & &:Nx3+ &ZN0 P&:  P&Z F&;N3+&[NF&;j3+&[j6&<N3+&\N&&=JS3+'&]J&P&= S'P&] &m&= 'm&] Um&K 5SR&Wjxx3+ 1&ZO1&\Ok.&DUj&@N3+7X&}7X&}&7X&}7X&}#7X&}7X&} 7X\&}7X\&} ~&$ ΰ3+~&$& ΰ3+&$ed ΰ3+&$mn ΰ3+&$PP ϰ3+' P$Q ΰ3+*'q$U ΰ3+*&$U q ΰ3++&+&&+&+&+&+& A&(Q ΰ3+A&(Q& ΰ3+'(d ΰ3+'(n ΰ3+'(P ΰ3+'( P ΰ3+U&U&&U&)U&2U&%U& &U\&$U\& &+K ΰ3+&+T& ΰ3+]'+d ΰ3+V'+n ΰ3+f'+P ΰ3+_'+ P ΰ3+o*'+q ΰ3+i*'+ q ΰ3+NH&GH&&H&eH&nH&aH& bH\&`H\& T&,u ΰ3+&,o& ΰ3+/',d ΰ3+ ',n ΰ3+?',P ΰ3+?', P ΰ3+A*',q ΰ3+B*', q ΰ3+7'&R7'&R&7'&R7'&R7'&R7'&R &2) ΰ3+&2B& ΰ3+'2d ΰ3+'2n ΰ3+p'2P ΰ3+q'2 P ΰ3+O/&O/&&O/&O/& O/&O/& O/\&O/\& &&< ΰ3+O'n< ΰ3+c' P<- ΰ3+*& <V ΰ3+8& 8&&8&h8&q8&d8& e8\&c8\& W&u' ΰ3+ &u7& ΰ3+'ud ΰ3+'un ΰ3+'uP ΰ3+'u P ΰ3+*'uq ΰ3+*'u ΰ3+7X&} 7X&}%-+&+&%U&U&%<H&WRH&%x7'&R7'&R%%O/& O/&%*8&Z8&%{7$X&}' 7$X&}'& 7$X&}& 7$X&}&# 7$X&}& 7$X&}&  7$X\&}& 7$X\&}&  &$'u ΰ3+&&&$u ΰ3+"'d&$e ΰ3+,'n&$o ΰ3+'P&$Y ΰ3+' P&$[ ΰ3+"*'q&$_ ΰ3+"*' q&$` ΰ3+U&'gU&'&gU&&)gU&&2gU&&%gU&& &gU\&&$gU\&& g&+W&< ΰ3+~&+Q&&6 ΰ3+'+'d ΰ3+'+'n ΰ3+ '+'P ΰ3+ '+' P ΰ3+*'+'q ΰ3+*'+' q ΰ3+8$&' c8$&'&c8$&&hc8$&&qc8$&&dc8$&& Yc8$\&&^c8$\&& Wc&u9&G ΰ3+&uG'U& ΰ3+)'u'd ΰ3+)'u'n ΰ3+ 'u'P ΰ3+'u' P ΰ3+*'u'q ΰ3+ *'u' q ΰ3+7X&}Mx7X&}Lz7$X&}&  7$X"&} 7$X&}&%- 7X&}QW7$X&}&QW ~&$M3+~W&$L3+~&$F 3+~&$%' 3+&$GT*dD@GW_O$+D5665"&54632G"3T%"5<$UdDJKPX@nW`P@W`PY@ %"+D3267#"&55C !$+>6*:.1?GTq^QIvh\!-QdD@Fg g W _  O#")'"-#-!!"""" +D663232673#"&&#""&546323"&54632v4/60-3/51 5=4>U&&gU"&gU&&%<gU&QfU&&Qfg7&(G" ΰ3+4&(D% ΰ3+&+L, ΰ3+&+V% ΰ3+a-&+TdDKPX@JG@JGYKPX@~W_O@%~~W_OY@ $+D5665"&546327&&'53"46` T%"5<#Q "R TdDKPX@JG@JGYKPX@~W_O@%~~W_OY@ $+D5665"&54632756673"4I `6T%"5< R" Q#vJ\$KdD@@Gg gW_O """" +D663232673#"&&#"5665"&5432v4/60-3/51H"415=4>! +)1H&MH&LH &cH &`H&QH\&aJ&,M3+>W&,L3+&,d" ΰ3+&,k% ΰ3+TdDKPX@JG@JGYKPX@~W_O@%~~W_OY@ %+D&&54632#&&'53:4"n7` T<5"#Q "R TdDKPX@JG@JGYKPX@~W_O@%~~W_OY@ %+D&&54632#56673:4" `6T<5" R" Q#vJ\$KdD@@Gg gW_O$#! """" +D663232673#"&&#"&&54632#v4/60-3/51=14"5=4>1)+ O/&MuO/&LwO/ &O/ &O&&O&&&O/&QTO/\&6&<M\3+6W&<L^3+'<" ΰ3+'<% Ͱ3+&3V& ΰ3+{c !ddD@  JK"PX@W_O@ ~W_OY@ $$$&+D#&&'53'4632#"&74632#"&R*7` j#S "T{c !{dD@ JK"PX@W_O@#~W_OY@ !!    +D56673"&546323"&54632 `6pj T" S#^R dD@ Jt+D#&&'53R*7` ^#Q "R8$&&Zc8$&c8$&&%{c8&Q8$&'Qc&2O+ ΰ3+&2 % ΰ3+.&uE# ΰ3+ &u!% ΰ3+&V&u^| &dD@Jt +D56673 `6^ R" Q#MT*dD@GW_O%+D&&54632#;3"T<5"{t@U]M +3*{m!@  Ht +'7'77'>RRSSRR>>RQSSQR>d{ 4@1JHU]M  +3'7'7#@ll@y=kk=H+{ 4@1JHU]M  +#'73yAmmA=kk=!(A@U]M +5!(AII&__n [$@!]L    +#&&'7##&&'7)A1 Z@/4:65 4:65 {Z$@!U]M +3#迅'H,{Z$@!U]M +#53'!{t&@#U]M +#53#__b{t UKPX@e]L@eU]MY@  +#53#3#__b'&{t UKPX@e]L@eU]MY@  +#535#53#__b&''b /@,]L   +3!333ZfZvZ:qH #/K)PX@+ g_K _K_ L@) g g_K_ LY@#%$ +)$/%/##    +"&54632"&54632"&54632"&54632$$$$$$$$$$$$$$$$M $%%$ $&&$ $%%$ $&&$ {t\KPX@e]L@"eU]MY@ +#535#53#3#______b&''&{t WKPX@e]L@eU]MY@  +#53#35#__bb{u@Jt +'3``}{u@Ht +#7#`uu`b{u @ Ht +'77'`uu`>>>sYkkY777{t YKPX@e]L@!eU]MY@  +#535#533#_____b&'&JT 1@.gW_O      +"&54632'254#"MNJQMOJRTT,&&sljsrkju?OQPOLT)J@G JggW_O%#)) +2&&#"36632#"&54>"32654&# "6>6);JRED]/T ,1(&/*T;)F*F@FP^b/ZH+-/-.&+IV'J@G  JggW_O#!''  +2#"'532667##"&546"32654&D]-TB% 6= 3(@JRE$/'*+3-V\c/[I,<,G(H@AS9-+&.-*;8FD)&f 3+$MFH)&f 3+$fFR)&f 3+ LF[)&f 3+!KF))&f 3+$ P@MJe g_ K]L   +2&&#"35!#3#3!5"&5466$G 5;DEPxt1_@ dXZWBBCuKs@3)%.4{@0-' !JK-PX@ghL@%gW`PY@*(%%! +7&'#7&&546773273&&'267#'&#"'+#?87vo?*?!#  a(K$$M5c  ]"WO:A:[p)Zy[SWbH " JX5ItRc8.K"PX@#$J@#$JYK"PX@g_K`L@&~g_K`LY@(&! .. +2&&#"336632&&#"667#"&&5466^6^'$I0?]3D>G;&  +@1G $L5c>CHGYmh8#KD8 JZpl]UV&KPX@ %"J@ %"JYK PX@! n_ KLKPX@ _ KL@$ K_ KLYY@$#! && +2#4#"#5#54#"#336632736[ZWmNCWFnQ>XG U0t*[F?'"^gYZVض d^I*)Mň 2#'+]@Z( Jf   eK  L+*'&%$#"!  +3#535#53533533#3###3'#3'#3'#3'#XNNNNh_vONNNNi_v**^BC__*@R@@R@|RRRtS?@0 / JKPX@, e ] K_ K ]L@0 e ] K_ KK _LY@#42-+ ??  +2####32654&2&&#"#"&'532654&'.546mj1_}[U@BB8<i+@ 1#&%6#6R[&BJ 0($5#7Xef9K/ 'LECF=\C$)*:+FWQ,#)):,BL "&*.14h@e"J  f   eK L4310.-,+*)('&%$#!  +3#53'#53'33733733#3###3'37#3'#37#7#7#-XL>3+P'k.\/k%O)1< IT*Z0w-R-< T_ D= V)?(@R@@R@әRRRRRٕ<8@5JIfK L +3#533333##fWWUbβe8NB::BN>*6@3J]KL +35'75'75#5!#77u$u$u$u$P5idP5iOOQ5ieQ5i/<@: *JKPX@:~  g_K` K _ K L@7~  g_K^ K _K LY@10750<1<//(&!%&! +33326654&&#"'6632#6632#"&'#2654&#".{Vk eG:lI+`$$n:dQgtYR]QPL*XF1  -C$"(4 (B ZbEg9GL^ePcR>.[=6-,D;#(384 $1C@@  J_KK_L,*$$ +"'532654&''#7&&546326654&#"n$''$'3rS>RPU,%M>>I68-1R>(!  K,*wȆz [2URLE=YgWJQKLw,(*6IR 2#+1b@_  eeg ]KL 0.-,'&%$"!# #  +23#3#####535#535#3&#36654#326drKACQui8SWWWWF$53;NJD6   6=Qw6Y6JDDzY {D =!'@'JK-PX@) eK_K_L@) e_K_LY@%$#" +5&&5466753&&'3#667uIc@:h-"$Y03h>-`Mhr*<PG âf_ &#NFMzM : _"D@A  fe KL"!  +3#3##'##7#537#533&&#3^`cLU_SR_UKb`.iB@R@@R@ b$U01TR 9^@[6 7 Je   e_K _ L42.-,+&%$# 99 +"&547#53>7!5!6654&#"'66323#!!3267"u~ /TDI8~@D2V"&m5eu7WCJ< :{9k$"r ^_&@!@/5OSU)@!@tQ=Y"K-PX@"  J@"  JYK-PX@!K_K_L@%_KK_LY@ +&&'667#5&&5466752\%$G*(K$#F.@E`^lee#L N GG Šda &uxyOD@AJ~ gU]M"" +!53267#53&&##5!#3# OV UL0 aPJ,.<@82@@'C@JP h pp3+1&1:X@U ~gge W _ O'':842'1'10.*(&&  +".54>32'2>54.#"'32##532654&##Pc66cPLe96cP@pV0.SqDZP.Sr>RLV>RF',)+E 6cPPc66cPPc65.UrEArV1Q[ArV1_EDCL%*(# :@+ * JK PX@9~  ~ f  g  W _ OK PX@2~ f  g  W _  O@9~  ~ f  g  W _ OYY@ /-(&::   +#'##3#3'&'2&&#"#"&'532654&&'&&546NE#y$D? IId"";5):)ND<?"* #8(;rbbX6_  ^ 5 0(,4 =   0#)6_ .@+eU]M +3535#5353YHH9@  * )3JKPX@*  hg ]K_  L@.  hg ]K K_ LY@".,'%!99 +33467'73"&'532654&##532654&#"'6632fKL  6#Ip%@F>40:4992/)5$E.GH+'/T6*  '1\T ?")#$!7'.>0)3 2):I-F&KPX@   7 6@ "!J@   7 6@ "!JYKPX@2  h  e  g_K_ LKPX@6  h  e  gK_K_ L@:  h  e  gK_K K_LYY@$;942.,+)%#FF%( +57>54&#"'663233"&'532654&##532654&#"'6632s))%1#E+@I;8QËKL%@F>40:4992/)5$D/GH+'/U6p'1&!.?71N5M>6 ?")#$!7'.>0)3 2):I!"$ <@9e eK ^  L +35#535#5333#3#!aWWWWZ8GYGGYGP `K)PX@ e eK  L@ e e ]  LY@ +35#535#5333#3#UKKKKXKKKKGYGGYGB@? Jgg K^L""" +32673#"'!!&#"#6632 21* $ 32) :FPT;E/ *kK-PX@%e]K]K L@#ee]K LY@%! +3#53532##32654&##3#aWW5}kRHfdY^[Nqk@kAOEVLGpNa_#N@KJe]KK_L##  +2##3267#"&5#32654&&*A$i   CKfkWPTef9L. '/#LJSNECF;.0 &.5KPX@$32J@$32JYKPX@(eK_K_LK)PX@,eK_KK_L@,e_K]K_LYY@ 5) +#7&&54677&#"'663273#'##4&'7"6657CA/:eh2 *L!#`4DCH^@#MD)JO>BY74)K>HU B#L,*m$/ =KMB$ 30"@!JK)PX@*~K ]K_L@' ]K_LY@ " "%" +#&&5#5773373#3267#"&'7hCQ LM#4[GCJw+* 4( F5#8*#r{9C aDUFh`JK)PX@aK_KL@a_K]LY@"& +366323#5#4#"#Y4acOWOxZCX(#)*]gWe^aD|/@, JaKL +%#5##366773|V%IZZ>iPU@"D"UF#_@ JK)PX@aKKL@a]KKLY@ +%#5#'#33>773#W)=WW gٰJ5s4 &D 5@2J]K]L  +5!5!5!!gxD6PD'F 5@2J]K]L  +5!5!5!!X p#:DBn=#g JKPX@_K_L@!K_KK_LY@##  +2373#'##"&&5466"3266554&&kIrGGpP_EE`bllcX]$$^8.\6\.8\on[N6_??_6e )rK(PX@ #J@ #JYK(PX@]KL@K_KLY@ )) +2&#"#.'#3667366766  [   [^o  ~]~ R6I$';- U./L.V&'\,N.\"%W/E=7 *"0W@ *JKPX@]KL@K_KLY@00%+ +333>73366776632&&#"#.'#[J  _`\  2 0% hg\    `,X37."PX..#A\.:. /: '!,H@E( JgK_KL#"",#,!! +23>73#'#5267&&546"654&5F>:w^e[5$ I3 @'=58W06235<I:;?D! ,Ba#@ eKL +33!!aZ2OU#@ eKL +!!#XJ7"$-@*J_KL"  +"&54674632'>54&#"c:,D%-/N.TJ>X0O13R0=/, Q6/1kFIV'([^CwOaAK0\F^c0?JB0+7'%'%4$$$$5555( ,@)W_O +##"&54632 I4(0=G #@ J GW_O$"+#"&54632'7453(^AG "@gU]M$"+#"&54632!5!YI(S2FK PX@nU^N@U^NY@ +5353(5S5qFH@t+##5#LF:z@t+'3533L:HHe$@!W_O$#+#34632#"&9kt$%%$F'%%$ HRo &@#~W_O$"+#"&546323#$%%$[9k+%%$ HzV V3+( 0+5''5'(f5a :33#"|"tVj)KCR'H7=K '@$W_O  +2#&&##5Vt"F)j'RC=7H_ (@% JW_O""+&&#"#66322g9<93 ]H8f2~ !C= ` (@% JW_O""+32673#"&'2g9<93 ]G9f2 !D< 7Xj&}p7Xj&}p7Xj&}p7Xj&}p7X&}t7X&}s7X&}t7X&}tHj&Hj&Hj&Hj&H&ÿH&¾H&H&O/j&mO/j&mO/j&mO/j&mO/&qO/&pO/&qO/&qH&H&H&H&O/&lO/&lO/&kO/&lbBv#g@JKPX@c_&K'L@c&K_-K'LY@##+"&'5326654&#"#33>32%&/LZHQ!ZG?K%qlL0,[P6_?N\.tz d`aB [o%|JKPX@*~_&K_&K_.L@(~_-K]&K_.LY@ %%+"&553326554&#"#33>32bZYY\RLZHQ!ZG@K%p:w w W`gQ[P6_?Jb\.tzJwE4V\jKPX@J@JYKPX@!~g b@L@(~~g b@LY@  +25665"&546#&&'5!54:" *6j"5<% "R #Q GG4V_jKPX@J@JYKPX@ ~gb@L@'~~gb@LY@$ +5665"&546327566735!O"3H `7(%"5< R" Q#lGG4V\jKPX@ J@ JYKPX@!~g b@L@(~~g b@LY@  +2#&&546#&&'5!5w":4 *7j%<5" "R #Q GG4V^jKPX@J@JYKPX@ ~gb@L@'~~gb@LY@% +&&54632#566735!:4" `6(<5" R" Q#lGG}^ Z@ JKPX@K_L@_LY@     +5>73'"&54632#! j 2:u^ 57 99W^R f@ JKPX@gL@ ~W_OY@      +"&54632.'536673A ,0<88>1- 64 00 46lmR _KPX@g]L@gU]MY@     +2#"&54632#"&546!5^KRGGN]R -G@D  g c_L --+)'%#"     +"&546323"&54632663232673#"&&#"^4/60-3/515=4>X]q D@AJ d_L   +56673663232673#"&&#"A8j 2:1+3-20,2. >" ,-5=4>lmq [ JKPX@]L@U^NY@    +.'535!:2 i9)11 "G sGGlmq [JKPX@]L@U^NY@    +566735!A8j 2:) G" 11sGGWYq*n JK$PX@ _L@!W` PY@ &$* * +.'536673"&546323"&54632. ,0<88>1- 0/ && /0kYD`K$PX@e_L@ eW_OY@  +!52#"&54632#"&5467DGGX]D;@8e c_L  +5!663232673#"&&#")1+3-20,2.GG5=4>k^E*@'e_L  +!52#"&546הEGGwk0@-eW_O  +!52#"&546זGGw.Zb #/@ JK&PX@)  h  _ 8L@/  h W `  PY@&%$ +)$/%/##   +56673"&'332673"&546323"&54632W4FI71*#6 9QA + 5pE8!7Fw.Zb #/@ JK&PX@)  h _  8L@1  h  W  ` PY@&%$ +)$/%/##   +#&&'5#"&'332672#"&54632#"&54614QDFI71*#6  + 5 b7FE8!4Z\ %JK&PX@# f_  8L@+ f  W  _OY@" !%%  +#5667!52#"&54632#"&546*417 5 + GGf4Z\ %JK&PX@# f  _8L@) fW_  OY@" !%%  +&&'535!"&546323"&546324W(A5 + eGG.Ob'KPX@J@JYKPX@& ~g dBK8L@-~ ~g dBK8LY@%$" ''% +&&54632#56673"&'332673:4" `66FI71*#6 9Q<5" R" Q#A7!7A.Ob'KPX@J@JYKPX@& ~g dBK8L@-~ ~g dBK8LY@%$" ''% +&&54632#&&'53"&'332673:4"n7` FI71*#6 9Q<5"#Q "R A7!7A.Ob'KPX@J@JYKPX@& ~g dBK8L@-~ ~g dBK8LY@%$" ''$ +5665"&54632756673"&'332673O"3H `77FI71*#6 9Q%"5< R" Q#A7!7A.Ob'KPX@J@JYKPX@& ~g dBK8L@-~ ~g dBK8LY@%$" ''$ +5665"&546327&&'53"&'332673F"46` FI71*#6 9Q%"5<#Q "R A7!7A#KPX@J@JYKPX@]&K]'L@]&K'K_.LY@##+"&'532667>7!3###B# "_f_  '? K/J'(p6tJ5C]0K(PX@ J@ JIYK(PX@](K]'L@](K'K_.LY@ +"'53267373#'#'#5 6@cdc…r .LC]a":@7  Je]&K'L#!+33273###32654&##abs3_f!lNRHfdY^[2eLX$cBOEDU ")v@  JKPX@](K _'K*L@'(K_/K'K _.K*LY@$"))#$ +33663273#'#"&'#26654&#"UH NAVscd sY>Q0@GJRDAI#0iimo. 4/5^<\n\^ckPJ@GJe e ]&K] 'L' +3.5463!!!!!!#3#"&C*#5thlVZX8 .P@agONO(t ;DBH="")2KPX@ J@ JYKPX@*e   e _(K_ .LKPX@4e   e_(K _(K_ .L@6e   e_/K ](K'K_ .LYY@!+*.,*2+2(&$# "" +"&'##7.546336632!3267!&&#"35#"ug }f:$hVK/Dd5YP3O*)P>C?It=5E rm$>0LR: $7!6632/>=#Y]ul9Z  &?3# "T7Cx P |vxy{J4D]0K/I'(okG ,K"PX@#JI@#JIYK"PX@)g](K_'K_ *L@-g](K'K_.K_ *LY@'%"! ,, +"&'532654&#"###"'53267!6632=&9:"?CTY#X} .L8 6B #:bN `ficΩ^Aay8a&{@ JK1PX@'eg &K'K_*L@$egc &K'LY@&%4%%1 +6632#"&'532654&#"#!#3!37CxM/>=#Y]ul9ZZZnZkG P |vxyM.U J&K-PX@J@JYK-PX@" g(K'K_ *L@'U g(K'K_ *LY@! && +"&'532654&#"#5##33536632r&9:#?CUX"XXXX":bN `ficay8aD *@'a]&K'L +5#!#!3yYZV{UGi *@'a](K'L +%#5#!#!iWPXJ32aD8@5 Jga&K'L##+5#4&#"#366323iY=D;^;ZZ:k8doV:9]XUGh6@3Ja_/K]'L&"+5#4#"#3366323OxZCXXY4acOWe^(#)*]gV] Y JKPX@oU]M@U]MY@ +#'##'##'5([Z'T2222TG@D J~K`L  +"&'57557537726653*kkkkV[j.V#O~F%A$O$A$GAGOG@HK~NEd:a *@'K^L   +!3!!3TZ8{ZP6a@6@3JcKL%# +#"&'5325467####33^V("hKR6b^Is(P&lNW9TZ(KPX@J@JYKPX@g_K_L@#g_KK_LY@$#  (( +2#"&'532654&##57&&#"#466hct?b84nW5\))a,UJVV>F:\TY:xWK1Z@?a8RKD@CA&)gQ2JwE$ ʰ3+=%-@*JH_K_L&%$( +32654&#"56632#"&&5466MCMm9/`Ige^K- /#Lo=Bf`KH{0 [bDpBpX\`F ?uPMLS]rj \",@) JK`L  +"&54667336673'326678:;gAa   ^*FIY'0"5T1 >13M2 7CUe,qHG2FB#E@Bgg]K_ L##  +#532654##532#532654##532:KmLRVT'UX 8Ki49UN$R*14YCOC*E*a*,6UCPA'C)1 %@"c]L  +"&54633#"33Ly}ibv^ }gewPSW2a@>@;JecKL  +"&'53265!#3!3)#48ZZlZdL:G?.Hme  &7 3+1!I@F  J~_K_L !! +"&54667'572&&##"3267I?j?Gp1!.X+Sfha_2k1+h ocCV-CxESCD>BHS#A@>JfK_L%# +#"&'532655!55467#KD% !&OWVK)./>H:u$+#h +K(PX@ "'J@ "'JYK(PX@* fK _ K_ L@' fK ]K_ LY@!!!!+!+&%    +"&'532655!533#5467##5>7B% !&O_K  )2  K)./>HK&WV:u$+t %T" 7:&$$#L($JKPX@! f_K_LKPX@% f_KK_L@) fK_KK_LYY@ ( (&# +7#36632#"&'732654&#"'&&'Qb]XkKKkNryyqpyzrgPQp[oo\|j<@dJKPX@fK_L@fKK_LY@  +"&''!#3326533'&&'n|( Qb]0G7[^ZdP dj8J%c]2w3<@}1@.JfKL +%6673#'!#3'&&' ]cPQb]CPQ=;M6\<@ 7@4JfKL  +1333##3'&&'6677#aqp]gou., "A6?|}<@@@P#b}&D@A" JfKK_L&&$" +#"'532677'!#36673'&&'l#o^;*16<LPb] ]4PQ)afR 7?41=;M_<@;&hyT3+ k4@1 JeKL +53533#66773## TZ^^>i&jIZ&OUUO"D"mU@&ak'@$ JKL +%7'#3667737#'ceIZZ>igc)fjrb|Q@"D"ɎR2TњQ k5@2 JeKL +%7'##53533#667737#'ceIZTTZ^^>igc)fjrb|Q@&OUUO"D"ɎR2TњQaN (@%JK]L  +7!!Y:lY#[N#P -@*eK^L  +3#53533#!aKKZmm8+MRRM%P #E@B e _K _L! #### +53>323##"&&'"!&&267!>LidO::NgkKJpr qpsq-sJFbQPcFgTUf@;e e ]KL%! +75332##3##5#32654&Q5}kRddZ[HfdYuK nd;g@VKuuBOED{$pK PX@#pg ]KL@$~g ]KLY@ $$  +2####"#&&54633#32654&o5}kRZ+'JJT[HfdXnd;g@)  JGg_K_L$%&E +%66544#''7'"#"&&54663232654&#"ig/-##&54&#"'6632!533#U{,E(;8&L%1,bA[kGHUcc5'CB'*3 ;%*PO?i>wKXXKPX@ J@ JYKPX@KL@KKKLY +36673#'#73L9 _Z886R^yN!,M##N-6,4@1& JKK_L$" +#"'532677.'#36673>73 z^8(16A ^Zp sZ  xZ wnR 6@83/LP0^&#i45$W56(}KPX@)e eK ] KL@'e   e eKLY@  +2####53533#2654&##)~`ZYYZmmO]dV[_(ider[A..A3?QEA(=@:  e eeKL! +73##5#53332#'32654&##mmZYYZn~`O]dV[_7A@@AInjcerG=RDB-[$@!  JKL +#57'536673OOOO &e{55$551b S++,(@@="  J#Ie_K_L%$!$$) +#"'532654&##532654&#"'6632OFPTvzO*d,RbfbTUdUL<3T*$/pD_v#GVYFem)QEF@ALB=6: @%'^'>@;Jg_K_L$"''%#$# +354632###"&'532655#%2654&#"VPHV\T:[U- !1/+.&")4JdN@LRg^N8CJ,&)27.4!>@;  Jg_K_L !! +"3267#"&546632#52654&$KKDC2:)`n9kJJqA~LZKGL H tgHm>DiKr QK1PX@]K_L@g_LY@  +#"&&5467#52654&#"lHInmI<=yynssxq1g\nn]]n\/NpXH\1xKPX@ J@ JYKPX@e_L@eK_LY@  +2&&#"3##3366% %ZhYDhQekfJ/f1?9,.@+&J]K_L! ,!,!& +#"&&54667&&5467#5!#"2654&'_;T,sFl=;\27+a+ GM?>,P2T!EX=m}4bEG\5 #6)$ JJ<KSM?L% *J;GO9S ʰ3+/  ʰ3+\; ^@ JKPX@_K_L@K_K_LY@ $%$! +%3267#"&54&#"#336632xM!!5LJOPi`YEmMuw]J[M4^Zyj^26~\1dKPX@ J@ JYKPX@_L@K_LY@  +2&&#"#3366% %ZhYDhQekf1?7R1@.J]K_L%%! +5!#"3267#"&&54677ZI{v,U+(Z7gKiN|NNMWMUhp(a @fKL +!#!3!3Z:ZlZN|.a7&@#JaKL +!###33.533#RSh}T@WQ#h7q@K!YE@B Je_K_L%"$# +53>32&&#"3#3267#"&'?SiqT$!Q0k zq.T)(U; ;LcT*LwLr N&D@A&%$ Je_K_L%'#% +32675#5!# 57>32&&#"%+C5vFTIKhXp=k'@$  JKL +57366773%##^Z>ijIZ>d"D"I=@U@)"-@*"! JKL +73737##77'#3.55^hɱTZZiեS^Ok>J!~"#h@K!;i?@<  Je]KL,% +!###575327'%&&##27_gZ^^vGAGC [JYf  =NN > Da&4){&U /6@3 /."  !J_K_L%-%' +7&&546632&&#"%#"&'532654&&'&''(:fD:b)%X.CD6C@Cu&QD_jV>5#0(0 \K PX@!pe]KL@"~e]KLY@ %! +!#!##"#&&54633!3ZZ'+'JJTnZM)  ;T.&=#3|@JKPX@ g_K_L@$gK_K_LY@%$.,$3%3 ## +"&'532655467##"&&5466323732>554&#"X?y7;|>eghR_|=E}UNe N9N.h_bd)WVct2/BXanP;/`ij(BS*8ux|JuCGv JK-PX@& gK_K ^L@$g gK ^LY@$! +%!#"&54632533#54&#"3Gd4>?B3$ZggZ$MM3?.5862& .k ʰ3+ "7, ʰ3+<W@JGK PX@cK_L@gcLY##$) +7&'#"&5463233267&#"(8B/8EA6*&Z)!" $1G)"!&<45<)'!|$KPX@"!J@"!JYKPX@_K_L@K_K_LY@ $$ +23327#"&&''#&&#"566d"+i` ((0$f`z  0'_@(*B "H;b&*.C ^J#;@8Je]K]KL#""$!+  +32###32654&##32654&#^ӊ~J@JQtZZVLWVwVRV[[Y@Q  OMhf<;;8GC=A= $~&$Pa$&(P($*&,P/Z$&8Pa&/ 7a&1 :{ /@,e]K]L  +3535#535#5!:AHGHU*,6&5#%,KPX@ J@ JYK PX@( pe _K`LKPX@) ~e _K`L@3 ~e _K_K`LYY@'&*)&,',%%$"%$$ +%#"&'#"&546632!326732654'"!&&?;+%I/z:lLirXR1N/!$ ?O@"2EVFo4\a" 6SQG]!"!"8[@X76  "!Jge_K_L42.,+)&$ 88 +273267#"&'#"&'532654##532654&#"'6Lfg *=)@%4' 6!ov:^"]75huiTC3O*)P7^j *< (A"ry/: ? ub@EM^Z<," B7GH&=I"J;IU@KL +3#3XX$&*P+@(JK_L  +"&'532653&   *XHG#1kKUNK)PX@ eKL@ e]LY@ +3##53533533###XQQXXPPXHIggggIHjD@ JKPX@_KL@gLY%$ +754632&&#"7#QaP1*)/j X2-gU E 4?R;8LZv jV@ JKPX@e_KL@geLY@ %" +36632&&#"3### H`P1*)/XHCfT E 4=H7'" #/0@-Jg_K_L$$)*%" +#"&&546326654&#"4546324&#"326'sGo@tHp?LRRJ<1/@7   A}YA{ T7_ll_4R2772vZFM)&f 3+JKPX@ J G@  JYKPX@_K_LKPX@_KK_L@gK_LYY%%%$ +!#'##"&'732654&#"'6632JE N8" DU$."8PQ^17SbPW12D MY=@:Je(K_*L +"&'53265#53533#&   *KKXKKHG#1KGGKU8@5g(K_*L  +"&5463333#'2655#"(@; J~_K_L$$# +%'572&&##"3267#"&546&Kj1/R7Fub\]2k0UťCv BSDPBDOO)teem>@;JK^K_L%# +#"&'532655!535467#HL* ")REUH'.Q>/:u$*^ +KPX@"'J@"'JIYKPX@*K^ K _K_LK)PX@(K^ K ]K_L@& eK^ K_LYY@!!!+!+&%%# +!#"&'532655!533%35467##5>7FM*!"(R["' )2 JI]H'.Q>/HH:u$*] %W$ 9;O~ #@ e]KL +3#!#3#L/@?("'.@+J_K_L%+$" +%#"'532654&'.54632&&#"hV^<"N+3=D7$?&aO)K%#=,75$)A%HOH,(**%;-DM=*%"'9.8#2=H@0/  JKPX@%   e_ K  _L@)   e_ KK  _LY@!FD@>;953-+)'$" 22 +267754&#"'6632#'##"&'#"&547754#"'663265%3265`c>i[:5*L!#`4b^@#NC7T3>,P\bp%M',^OT\5.FVYOdM7+C[#]aE C4BV^L,*-.!(RN}B2;,,QI083-*KN.y#!-8K(PX@J@JYK(PX@"e_ K _L@-e_ K_ K _LY@640.,*&$ !! +2632#"&'##"&547754#"'6632654&#"3265~,ByHp?sEm fFX^bp%M',^KRQLLRRJ\OT\5.FV#ONA{Y>::>RN}B_oo__lle2;,,QI.L#(3KPX@&%J@&%JYKPX@"e_ K _LKPX@&eK_ K _L@*eK_ KK _LYY@1/+)#! (( +232653#'##"&'#"&547754#"'663265`c9=WGXF [=@W"_773#'##5353c gj=WLLWA4 5]AZZU N@  JK)PX@KKL@]KKLY +77'#33>7737#'EC=WW gIh'jzjQEi6[5s4 `Q1Rm5  #g@#" JK)PX@eKKL@!e]KKLY@  +77'##53533#3>7737#'EC=WLLW gIh'jzjQEi6[5]AZZA4 `Q1Rm5U;@ JK)PX@ KL@ LY@  +7#XXX!#! AK)PX@eKL@e]LY@  +3##53533#XFFXEE^@ZZ@t" E@B e _K _L  "" +55366323##"&&'7"!&&267!H jd @?mDkBIJ6LHLLLBrzzrBz;rQUMMUgaTTa5#&2KPX@ J@ JYKPX@" g_K _L@, g_K_K _LY@('.,'2(2" &&  +"&&546326632#"'254&#"2654&#"*Ho>x7U 6):A6&:n;PKLPMNN D}V#%G7!9$OyDjB#$%p]_mic^o7"&RR0"+ JKPX@' e _K _KL@+ eK _K _KLY@&$++$$ +53336632#"&'#3##5"326654&SH NAcyyd>QXRDAX0@GAgI#0. 4;A``h\^ck5^<\n#)6@&.# JK PX@,pg _ K_KLKPX@-~g _ K_KL@1~gK _ K_KLYY@+*31*6+6%$")) +2#"&'#&&#"#&&546323366"32654er6hJ1MX !"LEL  I R)SD /;JH#S~F&/%# =KJ'-J_^m_ /#+8KPX@ - *'J@ - *'JYKPX@_K_KL@!K_K_KLY@ $55$%& +%.554#"56632336632#"&'#5&326654#")AJ= &3AIS;erAc.Xs0IY(SDDbImPFyPWJ'-UG6_<_7d"* JKPX@' e _K _KL@+ eK _K _KLY@&$**$' +535467##"&546323733##5'26754&#"Q@ay{b?P FRRXRFDWHFF@D0"00#I@aa[^fiq__k7 ")6@(JGKPX@%g_K _KL@)gK_K _KLY@+*20*6+6))$* +5'7467##"&5463237376654&#'226754&#"&Q@ay{b?P Fb',(@M'RFDWHFF% "00#IR`%5 %)5F9$3//[^fiq__k )@&Je]KL$!  +32#'#532654&## bk<2btc8@=:dPM:KA2.0+'u6" :@7 Ja_K]L&$' +#5!576654&#"'66323533#S3F.%<<0#R;LXE=gTbc>4W2%+3:'PC>a;iI1@. JK]L +3'#7333>73:5R^]x8 r^NhIF35< 38@5-"JKK_L32)($# +#"'532677.'##33>7336673a:I2$ .5 Z  X]ZL  ][X JX[f) H@A#&,1) )2.1_>2 ,,Zb90!.v JK)PX@)eK_K _KL@)e_K _KLY@-+$'" +#"&'###53533#366324&#"3260yc?PXMMXN@cy[FJSDAXJE .  " N?[[?F- "0ee\\ckk0!.~ JK)PX@* eK_K _KL@* e_K _KLY@-+&$!!$' +##5#53336632#"&'#4&#"326eXMMXN@cyyc?P(FJSDAXJE[>WW>S- "0.  " Kiee\\ckkU @JKL +#3673XXf 801I#&?@<  "!Je_K_L$,$#!! +4##53254&#"'6632#"&'5326xMLJ9TM ,f>7Z6BBJQ|:\)\[U[ G<@7A!)TAD\^LmyP/R&m@ JKPX@"_K_K_L@ g_K_LY@#!&&$#$" +#"&'53265#5354632##72654&#"KV0 !!.)xxUOMP\S:7,-% ")INYG 28G/JbL@CSG)&&18)5#!>@;  Jg_K_L !! +"3267#"&546632#526654& HIFA/8'`n9jJqWr8OgXST K ztQyBHMz7c,@  JIKPX@-  ~K _K ^ LKPX@9  ~K _K ^K ` LK)PX@5  ~K _K^K  _ L@5  ~ _K^K  _ LYYY@!! (& ,!, +"&546323&&5533733##7#'#'26554&#"dxyd>OX8CDCzCED` P1UEBYGGG .! 3PHH"0I]^dkq_`jUc SK)PX@~K^L@^LY@  +%33##7#33+DCzCEDtX;HPUc?"+("JKPX@*~ _ K^ L@.~ K _ K^ LY@!'%!  ++ +23733##7#4#"#4#"#336632366[Z+CDCzCEDcmNCWnQ>XG U0~&\"^g뜜HYZVYd^I*)Z.,Uc"JKPX@'~_ K^L@+~ K_ K^LY@  +23733##7#4#"#3366W`b9CDCzCEDqxYDXG \"^g뜜HWd^I*)UKPX@  J@  JYKPX@]K_KLKPX@g_KL@gK_KLYY@  +3&&'#7#33667A2, 6@B?AKXF S9S¿ ^G^14Uc!L@I J  ~  e ]K^ L!! +3323733##7#'#32654&##UVh$9 h6CDCzCEDL~>E4>RL0>$H,/%1#.@JKPX@-  ~ _ K_ K`LK1PX@1  ~ _ K_ KK`L@/  ~   g_ KK`LYY@!%$+)$.%.  ## +2####3267#"&5#577335462654&#"4>KUUXP*5GOLP 4K31#!G9?P-aD K[7*!v{"G`-$-4$A*8@5%J_K]L * *  +2##532654&''7&&546"6654&SY0%.=vpGO;19=J`Q+/66).UL7P&9D.XfO2<1?>'RBGYE.*,8 '7$(25"!)@&Hg_L!!% +#"&&5467&'72654&#"-/wHo>~yU<>/)bxQJMOMNK*gF{?sNt[d$:&!FGhUPfaXRhU#~KPX@ J@ JYKPX@_K]KL@ K_K]KLY@  +2&&#"3##3366L" DUXF M#ScOE ^170 eJ 3+U@KL +#3XX U#^@  JKPX@_K_KL@K_K_KLY@ %$$# +%54&#"#3366323267#"&;?SGXF \5^cA(GBHC_c H+'_ePGPU#fKPX@ J@ JYKPX@_KL@K_KLY@  +2&&#"#3366L" DUXF M#ScO ^17 5@2J]K_L  +"&5467#5!#"3267-w:6q_jVP%D F yPoHHkjWeNQ(x@ JK)PX@  ggcL@( ggW_OY@%#(($#$! +#"&5463233#327#"&"3354&1>??3 Xgg$, /QE9#+ 3<.47 g6/1 FU.'U<P"U JKPX@a_KL@aK_KLY@ $" +!#4#"#3366323#32&&#"3#3267#"&&'GDkB(M@MH+DA.El@ARg1 I AX] N7qY_"%,6@0/*)%  JKPX@!_K_K_L@%K_K_K_LY@'&42&,',(#'# +766323737#"'532655467##"&'"%&&4532654tg5U FMMu{vKOwEO6p\p 8@I% J[H>QJ ()G?st"Q*QF - Qqg aY6F>7NSWaN@ JK)PX@KKL@]KKLY +7737667737#'#5RW  gj,WRs ,& 1?+&f"Y@  JKPX@_KL@K_KLY@ $ +773366327##5"%54RG \3`bMMWXRGWE I*)]d?4`[4"kKPX@  J H@   JYKPX@_KL@K_KLY%$ +'7336632&&#"7#5WH S8" )H+XW b,@Q-O50?0"+6@3 +*!   J_K_L%-%& +7&&54632&&#"7#"&'532654&'{$'oZ1U%"J'698Gs#&tb8Q [/C<3I7+DJF# '*?8+NPP+$++UJ~:N# RV 3+5"#+@(JHg_L$%$( +32654&#"56632#"&&5466zKf=NQLLGB &avrLp=J7(jvw5`v^QO`FpsEVf,@) JK_L +"&546733673'32667b01@. JfLKML +13#'#7'&&'c`9<78>£0.& A&MK$$3+"&J;$$3+& >& @&LM$$3+$>&P8U&Ov$$3+&& F A3+3+&Q*$$3+<8@5 e  e]LK]ML +%##!#3#3!#3[Ea'r>HHfbShhAIhiAJ"&KP$$3+ <J< )@&e]LK]ML +!#3#3!JHJ&N$$3+D& @J&L4$$3+J$<&P{J< #@ e]LKML +!#3##JGWk%&N9$$3+& @q%b<&#&&L$$3+%$<&PI&Q$$3+b<(@%JcLL  +"'532653,.)WV D34-_Vb#"&J$$3+J< @ JLKML +366773##JX de@X<" 3J#<& J<@LK^ML +3!< I<J& AqJ<&'mC C3+J#<& J<&N 3+< ,@) JLK^ML  +%!5'7373%XWv&II";7 M:cJ<%@"JLKML +#4667####33RLOy<g1*  +2<0J$<$@! JLKML +###33&&5$kOk!<Q <2N#HJ$& A-J$"&Kp$$3+J#$<& CJb$<4@1 JcLKML$# +#"'53267##33&&5$WM-(*Oi#<_V D),Q 0H& @0H"&R$$3+0H&L$$3+0HT!*<@9&% JHG_PK_QL'-*# +#"''7&&5466327&#"4&'326H:v[U:"0#(';xZ+J&/'&%D)<[Wb%=]UXJ#1"1'sIWJ48&qG/LUxc/Hy0H& A33+0H&Q]$$3+0C%@ #"JK"PX@#e _ PK _MLK'PX@.e _ PK ]LK _MLK.PX@8e _ PK ]LK ]MK _QL@3e _ PK]LK]MK _QLYYY@ %%  +2!#3#3!#"&&5466"3267&&7.5,Vu;;uZXVTY% &CGGGJXVIIufhuJ< -@*e]LKML    +2###32654&##kjplGWW>AK>AKAK>AK"UbkCXrfWb=SGJ[L 0-248~ $MJhhsKF <!@]LKML +###5WE& @ E"&R$$3+E&Ln$$3+E$<$2@/JcLK_QL#&%! +3267#"&5467#"&5332653p-52.!(muXIFDGXF-,t-82,$CshiIMMGgp:;EEU&O$$3+E&QK$$3+< !@JLKML  +336673`|  |a<#39v<'@$JLKML +!&&'#36673>73b  b_VV  [U]  ]Uk<9<#QC(Y"H,)n& Ax"&J$$3+& >\& @b< @ JLKML +7#373#b`ad'<#@ JLKML +#53Y`<b&  A"& J$$3+&  >&  @< /@,J]LK]ML  +35!5!!/78I9FI&  A"& K!$$3+& N$$3+3vGL)&f 3+E @W_O$" +4632#"&E/'&//&'/a/,,//,,2,2 @  3+G)@3G3]@a*0 ʰ3+(* @ JL +!!57'5!*TTTT444P)*@'%JKL)) +336673>73#.'#&&'bo sY  yY] ]i oP0^&#i45$W55630L6g#&^0P4~2@/Jec&K'L%#+3!3#!#"&'532^ZlZZK@! <=/6NwIHID{&O@L Je Q ] &K ]'L&% +!33##!3#5!#3>7#!B0Z;fDlZ[VV7$A2 /9 M9ZjI >OQ:6@ 'M@J # J  g R]&K ^'L%$"! +3667&&53667!3#5!667#!5l*DKUW&'PW6U7 z&tg&&Z2 XK\_XG,0X@K PX@ JKPX@ JKPX@ J@ JYYYK PX@Q]&K_'LKPX@a]&K_'LKPX@Q]&K_'LKPX@a]&K_'L@"a]&K'K_.LYYYY@%'+%#5###"&'532667>7!WT  &?3# #M{J4D]0K1I$&o"'%"K"PX@JG@JGYK"PX@a]&K]'L@#pb]&K]'LY@ U"$!#+5663232654&#!5!5!32#"&#"G :6F?;-6?{LX&WS>e GH$ !=?N=$B*;L "'%*K"PX@  J G@  J GYK"PX@' e a]&K ]'L@-p e  b]&K ]'LY@)$$!# +5663232654&#!57#537!5!3#32#"&#"G :6F?;-6?ʫ屈LX&WS>e GH$ !=LN=L$B*;L -G6#@,s'@$ J&K`.L%%+7'533267#"&{OO&.$6LQ55!1/F MZ9@6 J~f&K'L# +53533##54&#"#54675ZquZ_]Z`ZzpLaaLa m`da_p a= -@*J~&K_.L#&+3#"&5467332654&'#5awwwwc1pxyn]\Za[sUd||dUsCPOD?JM=6S@P( ' 5J~_-K_ .L42,*%# 66 +"&&546632&&#"32675332654&#"'6632#"'S]|=>tP&K"4RZfe7Z9 ef[R4"K&Pt>=|\hGG _omYCCYmo_>>p3@0Je_-K]'L$!$#$"+4&#"'63232##732654&##%1&.>TUkZiVWaV_4=GTe|ibeoL@HL4+ <@9e]&K] 'L    ! +3#5!32#!3%32654&##j[ZiTW^V`|Nibeo6L@HL4a=@:e  e&K ^ 'L$! +333533#32###732654&##aZZjɓiTW^V````Jibeo L@HL4=&KPX@e_-K_'LKPX@#e&K_-K_'L@'e&K_-K'K_.LYY@ &&##+4663233###"&&%4&&#"3266=Dh^KZZGdhE.`KJ`--_LK_.fl]N^.6NfW]mVHHVXHHa4@1Jf&K 'L +33!3###!3'&&'aZ&y]\y{\w+53JJpE** 1@.f&K]'L   +!3'&&!'vu.FCFE3TCD$E@B  J ~e]&K'L $# +%##5##7>7'5!#7!"!.#FQ1[F/J:A:I/H[0>)'>0:P,44,N801-2a ?@<J f&K] 'L  +33!3!!3'&&'!'aZ&y]uw+F^\53JpE** ~`@ JK(PX@]&K_'L@ ]&K'K_'LY@ %'+%#&&'####"&'532673]n Y &%8.  #$]@2S(p,b-t9X3J>FDG@Dx5@2Q] &K]'L +!3#5!#3>7#!xZVV7$A2 /9 MM >OQ:6U@ JKPX@]&K_'L@]&K'K_.LY@ %'+!###"&'532667>7!!c\  &?3# #{J4D]0K1I$&oMaF-@* J]&K'L+!##33!!#467#SYri9OIM4f =&24 43+='3I@F  g_-K _.L)(/-(3)3#!''  +"&&546632'2654&#"7"&546323"&54632oHHpkKKkyqpyzrr \om\[oo\N=' ./ .D9@6Q] &K]'L +3#5!#3>753#!B[VV7#?2!U/9 M =MQ:63+7@4J_-K_*L+++"&'532654&&'.546632&&#">c&(c7I].L..T5>i@;`++N)AR*H,1Y8@rV XQ2G:DbJJk9ITM5F6!G]DRs;&5@/ J0 IKPX@# e ] &K]'L@+ e&K _ -K'K_.LY@42-+'%$%$ +333####"&'532654&##532654&#"'6632*%Z;fDlZE:i-.p1`cthfajiP@DX*+*{Msy#0F3ZjN.V^vRHBD>KG<6:"=+dK#1@.!Jg&K'L##$"+!##"&'#"&533267&5332673Zn`2P@~5bkZ?F2V7 Z?C4R4Z)0[[;=#<<Y9g/7KPX@!J@!JYKPX@0 ggc ] &K ]'L@5 ggUc ] &K ]'LY@!7610.-,+'&%$#"  //+%2#"'532654##53254&#"!#3>7!36#!/?: #CC<+1$*R'&N#(W5-L4 \N&θ*4W\ %15 (,%  Rr @9 ;@8Je]&K'K_*L#$!"+%4&####5!#32#"'53265C;?ZSU0#*1=1|NNŶSe L 8; +@( J]&K_.L$#+7#5!#3267#"& 3- .S^NNIG:L e`(%ȵJKPX@$e&K^'K]*LKPX@!ea&K^'LKPX@$e&K^'K]*L@!ea&K^'LYYY@ %$ +"&5463!!"3!2654&#!3!3#10//>11D09XZaZ&(#QF,%%.5 &+".|m@))D( >=@:Jc]&K'L +"&5467#5!##"3267/?G6 60+8  848DQNN-9< 7@4 Jg]&K'L##+5!#32673##"&55  CG5_@ZZBr4dl|NN;=Y6)[[ak7@4Jg_-K'L"%%"+4632&&#"6632#4#"#adW& #/9@m2dmZ4[=ZmiO>F_[[ xa('Ե!JKPX@&e &K^'K] *LKPX@#e a &K^'LKPX@&e &K^'K] *L@#e a &K^'LYYY@  '& +"&5463!!"3!2654&#!3!3!3#q10//Y%1D0:%Z[ZN#QF,%%.5 &+".||l#V)D(==#;@8!Jf-K.L &#+#"&&546632&&'!355!#66KkoHHpkKa^]]_`__`fo\\om\[Bh ~n A@>Je(K'K_*L +"&'53253!53#5!$ CXXXDIZeK\F#O@L Je Q ] (K ]'L#"+3533##5#3#5!#3667#3X`fXNUT+EEw!5#_|ED0F?&M@J ! J  g R](K ^'L$#  +367&553667!3#5!675#35M%~M#'JQuPKw[)V1 5=/6 @M08;k8F8KPX@ J I@ J IYKPX@Q](K_'LK"PX@a](K_'L@"a](K'K_.LYY@%#+%#5###"&'53267!8QS .M9 6ACFϩ^B.5)5V@S"-Jgg gW_O+* 1/*5+5&$) )($&# +%#"&54>32#"&'6632"3254&"32654&*XD|)LkBNO^J+W$ `*[b3MQ d,J"UG5B69+H+üTlv,7" "@gW_O$%%"+#"&&5463232654&#"_O3N+]Q3M,'+*((+*' 6zg6zen``nn]]7A":@7  JgW_O +"&&546632&&#"3267}cPR`=h $X*{spm?_($W :z_c|: I gdag NT%@"U]M+#!5TXs6JU, *@'U]M +3!####UXX22C 9@6eeU]M   $!+32###5#32654&֔nkft;GBDMKKYJ(00# EC@@ e eU]M#! +3#32###535#32654&թgtuu揑;MGIKYI(00#1'-@*JW_O$#&+3#"&5467332654&#".^]Zz~~zY\^LQRKNNOO^nn^MdcNP^a#)"K(PX@JGK-PX@JG@JGYYK(PX@c](K]'LK-PX@#Wc](K]'L@$gc](K]'LYY@ !$"$1#+5663232654&##5!5!32#"&#"3&$(-!+?.G"w|jWUO7P!.F #$6G9gHD=G #)*K(PX@  J GK-PX@  J G@  J GYYK(PX@( e  c](K ]'LK-PX@- e W c](K ]'L@. e g  c](K ]'LYY@)'&$ $1# +5663232654&##57#537!5!3#32#"&#"3&$(-!+?.Ginwxe{|jWUO7P!.F #$6@G9@HD=G -"GV@RHP9@6 J~f(K'L# +53533##54&#"#54675{XZcXFIJFXbXASSAN f`hdHCCHdh_f N" -6@3'J_.L"!!-"-  +"&5467.53>73'2654&'U\<>-: X2.*7[%G516)O:+602&+6 WE7aB)EDM27LD,.YsTVq:,JD%,H+C0)+O,'8,+3:N#4T@Q& % J2I~_/K_ .L0.*(#! 44 +"&54632&&#"32675332654&#"'6632#"&' k{rd"8)=>MD"4X6"DK?=*9"dr|j8QP C je^ll^ej C(""(l#3@0Je_/K]'L!###%"+4&#"'663232##%4&##326!-$4OPknbB>{FۘMYE/11$UF@C  e] 'K](K ^ 'L#! +333533#32###732654&##UXXknޛ;CD>iiiEMY,E/11$7"GD@U#*@JKPX@# e_(K ] 'LKPX@)  pe_(K ] 'L@1  pe(K_/K'K _ .LYY@! &$ *!*  +"&547##3!54#"'6632#'#'2655MZ+XXp%M',^1`c?&P'GUOT\4 RN=&#}B]aP/+FQI12;,, 7@4 Jf(K]'L+133'&&'#!'d  65.4QCD^!L@I  J ~e ](K'L!  +%##5##7667'5!#7"!&&#H)Q=BCuuuuBF--?Hء - T? 9@6 f (K]'L  +373!7###3'&&!']d^X c@3A@D56CѪa@J IKPX@](K_'K*L@](K'K_.K*LY@ $(+!#'&&'###"'532673\N  X !42  `(?T6&gLBH2 F#Gx@F5@2Q] (K]'L +#3#5!#3667353#NUT+EEt!5Fw_|1DpK"PX@ J G@ J IYK"PX@](K_'L@](K'K_.LY@%#+####"&'5326735` .M9 6AF-ϩ^BU-@* J](K'L+##467####33'OJOuF-V-Q-/Q7'" %>@;g_/K_.L!%%  +"&&54632'2654&#"7"&54632-Go@tHp?qQLLRRJKV A}YA{YIo__ll__o5B# %1-@*g_/K_.L$$$$$%%"+#"&&5463232654&#"4632#"&74632#"&BNuBQu?HU]\UW[YX+ D}VD}U^op]_mi[7"' ` `F19@6R] (K^'L +3#5!#366753##3NUT+@EPvv!5#2YsED0+#).@+J_/K_*L%,%"+#"&'532654&&'.54632&&#"og7W#&Z*AE <)0J*rY/T*E);>;.,J,cqLE:+;.8M>^cAB4(3*8P!"4KPX@3 2  JK"PX@3 2  J@3 2   JYYKPX@$  e ] (K]'LK"PX@,  e(K _ /K'K_.L@1 U   e(K _ /K'K_.LYY@0.*('%"  44 +23533##5##"&'532654##532654&#"'6\mX`fXov:^"]7.4KPX@!J@!JYKPX@0 ggc ] (K ]'L@5 ggUc ] (K ]'LY@!430/-,+*'&%$#"  ..+%2#"'532654##53254&#"!#3667!36#!.<8#@A='0")O&&J'R'>C3;%82U%"1 $.3 '*$  Y.|sQ#I@FJg](K'K_*L##%%%# +#6632#"&'5326554&#"##5Ӳ#W8]aEI(%9:5P XF!\_EUH'.A:F+@( J](K_.L%#+7#5!#3267#"&Ʊ). 1VK6FF81GYU(^#ȵJKPX@$e(K^'K]*LKPX@!ea(K^'LKPX@$e(K^'K]*L@!ea(K^'LYYY@ #" +"&54633#"33254&#!3!3#10//%r+;XX!OD,%%.5 V#*/8%)D(>=@:Jc](K'L +"&5467#5!##"3267/?D4/0+8  846EFF--9<1@. Jg](K'L##+#326753#5#"&55#5!ӳ553Z/XX.e=S[u72 VSzFU#3@0Jg_(K'L#)%"+4632&&#"36632#4&#"#UNF0$#!W=ZaX:"A{YA}YLPFI WM6&*@H_.L&$.+#"&&5467.546632654& hO>3cjqHo?dY!8!OA)M1QILSOM  0w^r|5gLZv$1#4B( ,P?HVWMJV+yG/ .j/ .j/ .j/ . j/ .j/ .}j .}j<3+3+3+ 3+ 3+}3+}3+k' ^! aG)&f 3+7`aG)&f 3+a:K1PX@e8K9L@e]8LY+##33ZZN^ JK1PX@~]8K9L@~]8LY@ +!###!#5#kZI@I|.baff@  JIK1PX@8K9K_=L@]8K_=LY@ +"&&'53267#36673:0V@)c=VnSZZ%i0MCQiE,jB-U`BK1PX@e;K9L@e];LY@ +3##XE JK1PX@~]:K9L@~]:LY@ +!###5!#5#5YzLLxU-UJ,=@:Jgg_.L(&%#,, +2#"&5466"32654&##532654&DCh;NJ[]wv>lC(D)OUSN`N5+NHN+T@HT  b[gnngLQe0IF?GLLGOIJJ=><=zKG@DG.J" HW_OCB;:KK+".5467>7>7327#"&&''2>54&&547"326678r_9=;+?& &*B2.\NbH me@ HO)! JA@8HK PX@6n~||W`P@5~||W`PY@VTEC=;'% ee +"&'7326'.#.#"'>3276654.54>732667#"&&'>32)4#8=/7F $!"+*(&2&%8 :E" |E^f(=7; %(%KVZ*@;2! @5 '3F. ")& TRCz,04 IX@U:9#"J!I~~|W_O-+II#&#&+'>3232667#".#""&&''76632326654&&54>73*3<<6)" HN *66$<)-) 1h  %24 $30 "" :6$. 1=9&77-=+| "."3S/-]Q &*#' 3267>54.#"'>54.54667>32>3232673267'6654&&#"06677"&&554&#"  40  !49-&'%  %! ,=&)I4 8L1#& " 5Z2,!% D0%<=="6 .* 7%  !>fNKg@(((+(' %$)/( ' +F(E2%& -& tz:+C<LP 71tE"+,3-P V@5$# J76 H  n  ~  |||||hW_ ONLA?><20.,&%! VV +"&'4&#"'>3232>54&#"'7>54&#"#"&&5732632>324  ,70C)VF"2 /72 &: 00 $!K &/&0!10.0# 0>$8^vq :1  &@KKEK A,:!!  l  *2'A3%/3oT#,@  + JKPX@&eg_K_L@$geg_LY@*($" ,, +"&54632&&#"33#"&'532654&##57hjdP"5#/g+1k2b^jtC]YS^ @ 74;:<dffwSP?=JC+@ J*IK$PX@&eg_K_L@$geg_LY@)'#! ++ +"54632&&#"33'"&'532654&##57^S$9&-C@PTQN#[ nm J  ~  |  |gg g  WW_ OwufdLJA?8731'% +".546332667>7>7&&#"32>53#"&54>7663267#"&&54667032676654&&'#"&54632>54&'3< 1"$  +$>YK**8*4"6#=q[59'$#K@)9O04:':98[(C/'7R' %&,HR' -1 % 7  !1# 1<(![ .2(7&  QX-SY2%-$ $5F*)(.Rm?0%PF+44+I:( !. B(/H4$9)'QE*$ ,<"%095$P8   :V23NcuA(@h>:~@{W >(=\ sJ  ~  gggg W _ O}|wuecQOEC:8/- +".5463232667'0>776670#"&54>54&#"'0>3232>7667>32032>73#"&5467667>54&#"9A1"$  1+8J=%?P1C) O?2:4 AL%0:< 1CKH -" %. %\db+"%4nW/- +0,!#/43!:+$mvcD (,$ (1-;B(|E"3k]9 @MICG$P>OO@LD-J~ggW_O43&%$# >>+".54632#"32667.54667663>54'77>75? 1"$#22*E=-:;oA73A00 !@) !A5`|CPa=:=pX3& !21(7'   '5]; 5C8ld)32&#">32326670#"&'67>54&#"267&&#"";%=%&T)  BR+4[u@---):cI( 27=DLT-+&/UqCG(!<!HA%6D(&E +WBB<?,%<20x,9$J(4$3 %# H+  *;>5`K+  .Nb5,8 <}qZ4*$gl\3CY&D-!11!B5We0Dq"a 5@2eU]M  +3!##'3#3#aGxCCCC6k5``^~@{z ~{xM = J  ~  gg  g g  WW_ Ovtkiba][QOCA;:42,* +"&&54>54&'"#"&54632>54'#".546332667667>7&&#"32>53#"&54>766326732>7p $!   .0"01<(![U9A1"$  -$>PB) W>4"6#=q[;@-$"L@) 9O04:-A?8[(C98om !# $3> #EF=  .C-^ NcuA(@h>&5. (7&  C}XCL%-$ ,AN*)(.Rm?0%PF+44+QE1 !. O(@h+"JD() 5=,) ʰ3+~n2F >@;  JgW_O +"&&546632&#"3267'~pIOo0]0PU+K>W)X*/VS) Zpl] 8" ; zSO|a ?@< eeU] M  +3333##'3#3#axCCCC:6[5``a &@# Jt +333#%5aL5M:"65bca\ ?@<JeeU]M %!+3!2##'3#3#6654'axBl=cxCCx$/Sm[>_65`1@54&#"&&546632254&'&"=Y0EqC ;d@0<" 0%"$#-'"1!./K+5#9#A3 3(M?&$<$%?(%# (EX{ % 4\;=hE 4*,S5.29))< 073,36aC   6NZ/556H(%'6Z4$(B(#--O:!  P8@10d vV |YL JhI  ~  ~g g  g g  W _  O:9rpRPJICA9:(& 88+".54>3232670#".#"32>54&'7".5463326677'0>7>77667>320>7"!':\S3@.."%#  /&DCF(6mY6 2,#3Jk.;!1"$  -',F= 8R,E07QB %&  G N `5%$ !RSF+ %!.Oe6&% #7A< ')+#(7&  6^;A1 ":e_/ $Ze5$ 8"'!** UL{@@=HG*Jr[6HW`PfdMKDB{{+"&5463232>7>7>766766732667#"&54>7>7#"&&54667>7>H3(!). )%7_VW/?|i# #9?>,="8f062 "$8> @@"(&,' /40#TyG=Y#3GF00$!SYP(QWg J:*;#( "=e~@Vj 5HNG2 8NUPUfd'8( DdV5-=&4^lFC2Zki'6whA  )2JK PX@( p g]K]L@) ~ g]K]LY@***2*1-+)'#! !,!% +7&&5463332###"732654&##32654&#EH̆FB-H+s\DS[v^KMc @>0Pa?S &F7ajO;:;3J<8E4A@>Jec]L  +"&'5325#53!!3#/" 2?BJHB1)?@<Jg_K_L%#" ))  +"&54675&&54632'2654&'"33#"B[YOKpIIr|vuyQSWg)*1S naGZQERf[nn]N=5=AJ0;J#i@  JKPX@gK_L@gKK_LY@ ## +"&5475.55333#"32653#'#:p6P+[iu*ZJisYIl f\ *ODXKJ=Av}6a*A #+K@H% JegWe_O   +"&54>323#773#2>54&&#"@Q"Bc@4D B'RCB/Qbo2 ;&KUyL.; ""(/5@2*(JgW_O  +"&54>3232676677&"#"6654'nq*SxNH`'.-^-,YI4% +{$)/L9A m]@}g><>Bd ?4 -'lo)H'< V M@Jg geU] M     +"&54632'2654#"3'3#"-2/L; qrnC\CP&%*[[>S$(++CF ?Uaa(4?@< J~gW_O1/%$!((+".5467'>76632326673'>54#"&1 ,!!7C%! :fO NR#Q\-;L+2-% ),$5 (&AN! ::2(+L/*U9<@4 2KO#;S@P 'J~|gW_O%$64.,$;%;##+".5467'7>32>73'267&&546326654&#"%0 ,PLR'+.4!/0*@*<)"  +M7+ ),$5 _$B),TZ%.&'1' 1o+%^jS.'{Q3FUg@d!$ LJ~~g g W _OHG54GUHU><4F5F)(#"33 +"&&54>77#"&&5467'667663273>73026676654#"26677 !*5S_W"$3$&  A #;#^:)'.v'B. 3T6N2GXx!B: "01-#"51O/BF=&{",!DA9+ G )87@ &D"(;!(@:5 ?I1GH17T,"J (+EPN; -N2(3<@ 7:"&J@G  %Jc_K_L#! && +"&&546632&&#"3267#"&'53255,Hn?ArH(M@ML+D9< 0 :z_c|: I ag ADI4@U:E$@JK)PX@&~cK_KL@&~c_K]LY@!  $$ +"&'53255#4#"#3366323 04xZCXXY4ac,9I4FWe^(#)*]gAD6r $1@$1JKPX@"cK_K_LK)PX@&cK_KK_L@&c_K]K_LYY@ %($&%" +3632#"&'##327#"&546732654&&#"4X-1j9sl,2?(KM'0Hd]j^*'()B2,+2-!"g<%i@ "JKPX@gK_L@gKK_LY@!  %% +"&&54675&&55333#"32653#'#3R11718S?K C8>4XFTAV #E13F BAlfA7B2,+2d]M'0a"*18@  '!JKPX@'  f _K _ L@+  fK _K _ LY@)32,+652838/.+1,1%# ** +"&'#536632366733#3267#"&'#"!&&267!_x46 vc;O E PP %/ M5AE%DMPFE >sz*((HP$>@$."0SPPSgY_\\.O#)4;g@d  ' J  e  e_K _ L65+*985;6;0.*4+4%#  )) +"&547754#"'66326632&&#"!#"&''2655265!M_an%L'+^1|(bD5R*.N2QYrqhBj#c;DRNR[5D@P RN%w@],1Hc[4o><==FQI12;,,^FQS:&@#JGt* +'7.55467733267'7654''$E- ` #,' dF %E< r $ yJm 3#!'H@EJ  ee _K_L#"%$"'#'%"% +734546632!!!3267#"&'#"!&&2:lLdrcV@1N/*S4g9$k  > VFzo7@@Hg`"m.?".5K"PX@()J@()JYK"PX@( gg _K_L@-W eg _K_LY@0/32/505$$%%"$" +746326632!3267#"&&'&&#"327#"&"!&&SD0 ~_Ec5YP3O*)P7KrC*&/##$ DC?I>=GlyK.2,4TA+  :799"$%!&,*{MxDSIAcXZb-O4Uay#2}@ 2JK)PX@+~~ghKL@+~~gh]LY@ $(#$)# +3#&&#"#"&54632332654&'&5432#"&'X  !  3H.  X   2?3  # D9<9 " B88?z7@)* 6 JK)PX@2 g  g  gK_K L@2 g  g  g_K ] LY@775310.,(&#"$"# +3&&#"#66325&&#"#66325332673#"'32673#"'  3<-  3<-X  3;,  3;,$=D p %>D $AA o #@B j7@  JK)PX@ KL@ ]LY +3#5&&546753'54&'66X6DE5X6CD5%$$$ U==:@;@29390.! )) +"&55!&&#"5663266327#"''7&'&#"2654'267!etdSM5M()M5Dh fBO:!4'rD3'4+ ^$;NHOF 8#>59[29ffeJ/NJESC$!(/6j@g   J  e  e _K _ L10*)#"430616-,)/*/&%"(#( !! +"&55!&&#"566326632#"&'"!&&267!267!etdSM5M()M5Dh fBFm?r?d^>GI+HFIFI32 -+*(JH)G_K _L988@9@64'% .. +"&&54632&#"3267&546327#"''7&'&#"2654&'-Lo=u,%IPNR$=!x5,7-0w8.7@N$MNPK G}RG jc^nBZ'($uM'*?/MV ip]2NP"@ J]KL# +7#546753#54&#"XbXXZcXFIJFvvz_f f`zvHDDW]'D@AJe]KK_L #!' '!%%" +%3267#"&554&###32#32654&B'GC?HQXbi7..3cd9>>JPGPDLKNM7CPE2.0+U3 &@#J H~KL +#336673>HXF >1bI^,3UB#wKPX@ J@ JYKPX@_KL@K_KLY@  +2&#"&#"#33663266" -6!:!:#XF I,&A#S ,O4^53/!# *KPX@ J@ JYKPX@g_K`L@#gK_K`LY@(&"!   +2&&#"&&'#"&54673366"3265" CV2:E1@HPF M8"#ScOM 6 OT753=C^17x!%/#,6KPX@*)" J@*)" JYKPX@!g_ K`L@%gK_ K`LY@42.-'%!  ,, +2&#"&#"&&'#"&546733663266"3265F" -8!:"9#2:E1@HPF I,&@t8"#S ,O4M 6 OT753=C^53/!x!%/c#?@ JHK PX@_KL@gLY#! +3267##"&'VR!V/X"+T)#   _#&m@ J HK PX@g_K_L@gg_LY@%#  +"&5#"&'5326763274&#"326Sc"+T)VR!V/)91J))L)5()45('6 hX F +,I-0L,)79))87fM@JKPX@_K_L@g_LY%#%" +7#"&'5325432&&#"CI&B& BBTGPڔGPPZJKPX@K_K_L@K]K_LY@ #$ +#'##"&5332655F [=YaX9=WGGH*(`d_HCb`Eds JKPX@(  eK_K _L@&  eK]K _LY@$ +353533##'##"&55#3267%LXXPPF [=YaL9=NI ((BH*(`d$HCONPF# .+%JKPX@$~] K`  L@,~K_ KK` LY@ *($#"! . .  +2#"&546"&5332655332653#'##"'#ZZX47ICXkKAXFS0|'X#]g_FBXYq_cH(*X,,TJ#  3+Q#Z@  JKPX@_K_L@K_KK_LY@ $%$# +32653#'##"&554&#"56329=WGXF[GHCb`H*(`d*&B J! x !-K"PX@ J@ JYK"PX@ h_K_L@$hK_K_LY@,*&$ !! +"&''#'&&#"566323663274&#"3267 @_-K_.L$$%#+#"&54663232654&#"0iUys/hUxv~CQPEEPQCftXítW# !@ J&K'L +3467'73L.I+4>;6&0@- J_-K]'L'%(+357>54&#"'6632!&5K&F85N)/*mDdt.R7iI6TP1;=$ ;#1fX8b`5P-*@@=$J%Ig_-K_.L%$!$%*+#"&'532654&##532654&#"'6632QCUU:y_8`,-h0`Ui_EFX[F<:R(,&qHpm#HU XG?`6RKBC;KJ=49"<,d( 7@4Jf&K'L   +!5!533#'5467#kP[hhU ˢK#O4L2?D@A  Jg]&K_.L +2#"&'532654&#"'!!66m~8`!$g/OaV]H,f:ndoSKOFK QP7 ,>@; Jg_-K_.L &$, ,$'%$+4>32&&#"36632#"&&2654&#"7Ge3.E\5R@]r{hDnA?NEE/F'"D1MyHK.Ph;#1qhpDQUDP'=+U7%@"J]&K'L+3!5!d%zPDz:(55@20J_-K_.L*))5*5#! +"&54667&&5466326654&#"2654&'')s|)C(4I8`=^x%>%,H+j4GF:7G#62552%2#E74EH74E2,>@; Jg_-K_.L &$, ,%'$$+#"&'532>7##"&546632'"326654&&Ge6'1F[6RA\q8gEDn@>OCF0F'"DMyHK .Oi:"1qgKl:ERTDO&< +T86# -@*_/K_.L  +"&&54632'254#"$Pj4{vOj5ywJ G~S~F}RJdj6# 1 JK-PX@ (K'L@ ]'LY+!#467'736Y c+J>'K I;,#*@' J_/K]'L'%(+!!57>54&#"'6632!64?;>)U(.3oA[h#C1?G$2.!,4 "=,%UI-D<"eS#(<@9$#  Jgc_/L$%!$%(+#"&'532654&##5326654&#"'632ƋSNv?Y'$^4SYg[=>0O0H53I+(U\uw  RJdoOJD>:J9048  Jgc](L +2#"&'532654&#"'!!6k}8^#/]/Q_\RD!(j?ghqrPHLGG UN 8'>@; Jg_-K_.L!''$$%"+462&&#"36632#"&&2654&#&8-. Y4dnxlRl6CKGB(H-%D/I./ugmPURFO&=#-T6]%@"J](L+!5!snM8}1 (46@32#J_-K_.L-+(( +2#"&54667&&5466"6654&32654&'^x%>%,H+jt{)D'5H8`<8F#<$4GFJMIMPVBEXS+@14F1Zie[0I4UB6L(G52%2#>625(4EE73E!H/T#(;@8 Jgc_/L" ((%%%"+%#"&'53267##"&546632'"326654&&03tVAam7fGqDJGC'G-"DI2.qgHk` `3+C,` `3+E-` `3+I?` `3+J=~ ~3+%{~ ~3+3t~ ~3+Au~ ~3+ U*~ ~3+@+~ ~3+L>~ ~3+C,~ ~3+E-~ ~3+I?~ ~3+%i& )G& 'g %& '( & 'c =& 'l  $& '^ %& ') $& 'g %& '( %& '( %& '('  vJ2= ް3+%~*{ ް3+~33t ް3+vA3u ް3+ ~U-* ް3+u@*+ ް3+vL2> ް3+~C*, ް3+vE2- ް3+vI4? ް3+sM' ' = Q==3+=3+6&' %@"a]L  +%"&5463!'3# glqkcc&tvCmX&I $@!a]L ! +7!2#'3#Xkqlgcc&vtCmOb+ &@#ea]L +#3#3#3+܍hEDb ,@)ea]L  +53#53#53HJFHH{Q!@JL +3#'(<_fFJ @GW_O$" +'632&&#"A*aa)&JIFPNNJ&  ><" 4@ JK)PX@ KL@ ]LY +#5'3YY  O} 4@ JK)PX@ KL@ ]LY +5'37'#XX5O ' #/;KPX@. g e     gKLK$PX@. g e     g]L@3U g e     g]MYY@.10%$ 750;1;+)$/%/##    +!5!3!!"&54632!"&54632"&54632!"&54632hALB  &   TLSL" !!  !! 4!!!!LIOK)PX@gK_KL@ggKLY@ $$$# +3#4632#"&4632#"& >@=Z65/ R@  JKPX@c_L@gW_OY$+$" +4632#"&5%%54632#"&|;;&51=P@MJ~~ gc_L32972=3=&$  11 +.5463232654&'&&54632#"&'&&#"7"&54632)8 &# G;&4   ' 9"  "(.85?   07 ;%49 0+%&'&&77Ew33!"#|)N)S!33wE")N)|# ( 5@KOSWf@ JH[ZGeeg    e  geee]LTTPPLLecTWTWVUPSPSRQLOLONMJIEC?=984321-+&%$"* +47#"&535!5!4632!!#"&547!5!&73654&#"32654'#5!5!535654&&54632n6-W$$E$$7 *  + ¶,n5O  '#++++++K$$ + %% +  m  ++++++N  #H&"4'2@/g_K _ L'%""""""""! +432#"432#"%432#"%432#"432#"\9::99::9Z9::99::99::9<<;<<;;<<;;<<;<<<5'2@/g_K_ L'%""""""""! +432#"%432#"432#"432#"%432#"59::9`9::99::99::9W9::9<<;;<<;<<<<<<<<<<5@2 Je]L +%#''5'7#53'75373~-~?~,~~,~?,~~,~-~?,,&@#GU]M +!'7#5}`4/45Y #/I@F  g_K_ L%$ +)$/%/##    +"&54632"&54632!"&54632"&54632C       q   !!  !!  !! 4-@*g_K_L"""""""! +432#"432#"%432#"432#"\9::99::9Z9::99::9<<;<<;;<<;<<<H:3+(3d GK PX@g_L@gW_OY@  +52#52654d1<<1'6(8227'" B  ɰ3+JG @ 3+{oHKPX@_LKPX@W_OKPX@_L@W_OYYY@  +77"&54632{-:|.k34>&0+7%SRT$>R0+7%SRT$t@Ht +#75:|.k51>@;J~|c_L&$  11 +.5463232654&'&&54632#"&'&&#")8 &# G;&4   ' 9"  "(.85?   07 ;%uBK)PX@eKL@eLY@  +33#7$1$)9  3+8yt5#@ _K_L"""""! +432#"432#"%432#"X9::99::9W9::9<<;<<<<<<<H]K PX@=nYXL?>1 0$ ¼ J# IkHKPX@1 0$ ¼ Jk# IKPX@=nYXL?>1 0$ ¼ J# IkHKPX@1 0$ ¼ Jk# IK"PX@1 0$ ¼ Jk# IK-PX@1 0$ ¼ Jk# I@?n YX L ?>1 0 $¼ Jk# IYYYYYYK PX@W  ~  ~  ||||| gKLKPX@[  ~  ~  ||||| gKLKPX@W  ~  ~  ||||| gKLKPX@_  ~  ~  ||||| g KKLKPX@e    ~  |  ~  ||||| g KKLKPX@k    ~  |  |  ~  |||||g KKLK"PX@k     ~  |  |  ~  |||||gKLK-PX@w    ~  |  |  |~  |  |||||gKL@}    ~  |  |  |~  |  ||||||gKLYYYYYYYY@"~|zyrp(+++-. +7"&'667.546327.546327.76327.546327&&546327&&546327&&54632>32663226632266322663226632>326632"' #                &  %/#) %' +F -, !11'% %+!60 )$, ">:  5/!)%    )%  / &*  " 8 1 +  #   %    #   $      l@U]M +!5`44 ='"" ^&")3+H3+#'@$]K_L$# +##5!#4632#"&5G55#@]L +##5!#555<O)@&a]L +!!<{O{F2 #/;_@\ J  g_K_ L10%$750;1;+)$/%/##  +"&54632'7"&54632!"&54632"&54632.2.45.2.[^   .65/4..6   @GU]M +%!5!#}44^LGx@#G"@,&G@x|GK&PX@]K_L@g]LY$# +#!#4632#"&5K5x|@]L +#!#55xHKPX@_LKPX@W_OKPX@_L@W_OYYY@  +'7'"&54632Dڷk.|ƅ>&0+'b$S%R%S$>R0+'b$S%R%S$t@Ht +'7@k.|518@5~|c_L,*'% 11 +&&54676654&#"#"&5466323276632A/8 (   3';G "& 9%; 70   ?58.("  "BK)PX@eKL@eLY@  +#533J71f*@'c_L  +%"&&546632'26654&&#"3T22T33S22S3#8""8##9""92T34S22S43T2<"9##8""8##9"5'@$_K_L"""""""! +432#"%432#"432#"%432#"59::9`9::99::9W9::9<<;;<<;<<<<<<<Ou2@/gW_O  +2673#".#"#66327@ 4 oK9zyt37@ 4 nK;ywr3%MN$4%MO$5)@&g_K_L"""""! +432#"432#"432#"]9::99::9(9::9<<;<<;<<<2 E #?@<JIGgWg_O$$$$$" +4632#"&&&#"56323267#"&"$/>0H:.$/>1G:  "N5  "M6 2} #?@<JIHggW_O$$$$$" +&&#"56323267#"&4632#"& $/>0H:.$/>1G:O? "N5  "M6 u2 &aO_ _3+$@]KL +!#!5!CeCB -L@ + JKPX@c_L@gW_OY%+$) +467&&546632&&#"#"&&732654&&'B2')$2U5YO%F%7:D4.O0[JE`1KCM+*E< '*@6"/;":&%"&'8+CM+G4,=/$" .H #OKPX@g_K_L@gg_LY@ $$$$$" +4632#"&4632#"&4632#"&H$&&$$&&$$&&$w%%$ %%$ %%$ Lt 3++  3+J  3+)8'  3+Hy' 5 @_K_L$$$" +4632#"&4632#"&5       !! 5#@ _K_L"""""! +432#"%432#"432#"59::9W9::9:99:<<;;<<;<<<J @ H_L$" +3267#"'@&JH&*_bPNNPDH0+7D%W  0+''7'77V34$44#53$23c43$34"53$33C2h #/;Gn@k g gg g  c _L=<10%$ CA54.54>54.54667,,6];AQ,,,,,,,,,,6];AQ,,,,,,,,-#2? ;,#,$&,+%%+-"2?;,#,$&,,%%*:&<FL@&54& JIED? + *JKPX@)  h gK _LK)PX@'  g  h gL@/  g  h W _OYY@>=('C@=F>F/-'<(<! +33253&&'667###&&546672675'"&54675"2327&B=21="?1;: =23=yCxM8It,5p2pzYG9_97v/+m/>@EL F    OpB  & \g[j ;aCEi<Pz:T1tG@C AdD@6 JHeU]M+D'#7'373#73'7#'#3DEEDCFFC-c22c--d22duxyuuyx,NVWNNWVz*/0+7'&&'6'6&')N)"Ew33!"#*#"!33wE")N)Hy'7O P P3+7O P P3+Pb4$@!U^N +33P@:b@U^N +3#53@H:P4@]L +#3#@:@]L +#53~:H(b'  b&  zKPX@a]LKPX@eU]MKPX@a]L@eU]MYYY1613 +3!!".54>3!!")EX/4hT32Ug5/XE)b,/0B<54.#!5!2#/XE))EX/4hT32Ug50/,,/0B<,@)Jgc_LL +72655467"&554&',2I^+1',*)1+^I5)#&z>=A$s.21/v#@:Bv'$ >,@)Jgc_LL +%#566554675&&554&'523 )4K]+1*))*1+[M1,$'vB:@#v/1.2s#A>>z&#<B@a]LL +3#3#=B@a]LL +#53#53kk>==5<@]LK_QL$# +3#4632#"&9aC9eCL^`JI ZD'2@/  J~_PK_QL$#$) +7467>54&#"'6632#4632#"&t+#! 4):E)L.PZ21!D,=$!&'#=JC5D!*+ }md (5@2J~gW`P%+$" +#"&546323267#"&546766553 +#" 6(=#(M.OZ21 D-<$"%&=IB5D!** [ &@#W_O ""+76632#&&#"zGRz5YB4`MCGI)/)/w ]!LKPX@J@ JYKPX@'_ K]K` L@$]K ]  K`LY@%" +#57733733#3267#"&5#aLP 4 5O*5GO*{{{{FaD K[7-;3@0Jg]KL +35466753#54&&'#;; J    g_K _LTSfd`]S[T[QOIIDCB?=<.,'%$%& +5&&546323663236632654&&'.546632&&#"#5#"'#5&&''54&#"7"5432754&#"q*1 ""/B1.0M*O63T1=hC4a1.R)>N(G08W2QO6"&6 >e/  %!> 6+")Oy;&,31<6!K*4(2L;#$%$(%"$% +7'7&55#"&54632!2#"&'''3267#"&'4&#"333265&&#!77%Y NaI8=MO^*10"2UJV[L?%9Fdz&"%+.}"ANjFP^/K9InAL7EWh5U1>O#PRJK? NSO17#)1$0@p& ZOK7H/)>@; Je]K]L&1A +73&&54675363253&'#5&#"#533!7Mfqm<<)')'<53 '^j6@4ICO&I 6AC'1N$@..Q!4AYP^c+I4=V.jf)7|x1554&''5#'7D% T1 ;G(%H!0+5'! D)G@j+Ӵ">#/1 P P3+#/5K&PX@ ]L@U]MY@ +5!# 44 - (6DNXbKPX@8   h g_K _ L@@   h gK_KK _ LY@KZYPOFE87*) `^YbZbVTOXPXLJENFN?=7D8D1/)6*6#!((     +2#"&546#"32542#"&&546!2#"&&546!2#"&&546"3254!"3254!"32546D MMHNJtK~&##&L15D LM5CK5E MM5BK5E MM5BK&##&L&##&L&##&L:dAmtvkkt 68NOOP:e@mt;eAls:e@mt;eAls:e@mt;eAlsCMPOOMPOOMPOO#/ P P3+#>/P ,@)Ue]M  +5#53533#ll4ll>o4oo4oG/ @l H@E JIeeU]M +55!!!7#!5!=6-KU?b77q1>E* ˰3+/  ʰ3+6<6 ʰ3+)4@ 3+ (A@2 >3 ? J~~  ~ gg g g  W _ O*)<:750.)A*A&$  +2#'#"&547754&#"'66#3265"&54632&&#"3267AB/ 9%/88*3@LK0<*3-JEZ]F4+Y+*/,6;*12c! 1 6ʪ/(SX\R 7 s7: <  w(N@A B/ . J~~  ~ gg g g  W _ OFD?=31,*&$  +2#'#"&547754&#"'66#3265#"&'532654&'&&54632&&#"AB/ 9%/88*3@LK0<*3-#7=%&&,27I994',06;*12c! 1 6ʪ/(Tf 8 +,/+ 2  &(/2K PX@   JK PX@   J@   JYYK PX@:    ~  ~g g  W _ OK PX@6   ~  ~ g g  W _ O@:    ~  ~g g  W _ OYY@$//,*('$" +#"&54632&&#"3267#'##"&55332655zLKEZ]F4,Y+*/-=&<@AH@1(6SX\R 7 s7: < +1:@G957&r&r & E@B JggU]M+!!5&&546753&&'67!&IORFBB..1524,8,..,l[Zjlh3 4wR@R; Pab&@!    JK PX@-   e e U ] MK PX@1   e e U ] M@-   e e U ] MYY@ &% +!'##3!##33#!#3#%&&'3166`Xg}adrsaYK73 rX MMB C7S&r)cNL)B@?J~_K_L%#))& +7'6632'67>54&'"&54632&(0Z4^m5(! (% C5! 9[S-A7#3' /-49_  %2g@d J ~   e g  W _ O'&-+&2'2! %%+"&'#####53533533#36632'2654&#"@8T>WLLWXP9irr{GKJGSAB -&IXX?aaaa? B,.|Iebdaf_ \a!U@R   JIe egW_O!!$$% +'"'532654&##57!537!5!~?xSqN._-[YfpBi<g`Bd9"PSDACAKL<,v`r@5;6 ~}vWI Z J  ~  ~   ~  ~  ggg  h  gW_Ous|wsuqpjhQPB@:7/-*)'% ``+"&&5467&&546677.#"327#"&5466323266326322&&54632#>54'6654.#"227'"&#"767&&'72654&'"#"&',20H*A! "$    #(     " 2C+G2  $ !"e= 2 -$(% +b    yt$![040 )& $:!Y5)) )  )  /GU'BP(4$**%2 7X!:$)A:%)> 2_ " 4+ V92U+4a_J@G J~eU]M! +33273#'#7'#3254&##aLE98Ufh[AFTsNf_XYffEc]ZkksJ:cG@D~ ggU] M +!##3532!6654&# hBBAofbs$LL^mcu<YGTKJao_i &_@\$# JH~eU]M   +27'7#####3023&4'66&/'y*A$if7h`Zfk=0752=44Do*9L. SNI A;8c%:_@\51)J~ ~gW_ O&&&:&:43-,+*('%% +"&'532654&'.54632&&#"733#5467###57'(((1"G;3-E)(47M^^a[@e5`c 5 )#00 1 2+,34`/ (N\jxR@OoaSJ>8,&   J    g W _Owuig[YNLEC'''(!$$$ +#"&'#"&'#"&'##53267.546323267.54323267.543233>54&#">54&#">54&#"7U !V67U !W66V !S4"F#?>~% I$"G"}}$G$"E ! ~}% D#  %% M  !%%Z  $$ 3 "X['sm'XV%  !X\''ZW"  $WZ''ZW" $QOOQ$TRRT$QOOQ$TRRT$QOOQ$TRRjT@Q ee U ]  M +#5!#33#3#3333ve fӔB?j*66`6Z6d6`6oXi)@&JHt+'76673#'#3_ _Z=7T^:3L#@#N-6R<u,O]C@@TH9JH~ggW_O\Z,))$'-+6676632#"&5463232>54.#"#"&&5467&&54>4&&'326*2 (Y)R'?S)$FhES\*&*@(3B(.'.j40Z%50C61O.$!)=@"$7&6'OaA46\#FBB?P @ J]'L+3773#5>BBzP @ J]'L+3753#>BB0P@"1%@"JH]'L+3'753,CĻ1P&#@ J]'L+!'773-BU/P"$@!JH]'L+!'73,nBƸ2P( LJK&PX@](K]'L@e]'LY@ +!#'73530Bɳ/P& %@"JH]'L +!5'73(kBsK4P&"@J]'L+!73.:B^.2P1%@"JH]'L+3573hBiSP '@$JH]'L +!753>B},WP -@*JHe]'L +!5#733;B7P '@$JH]'L +!773ԠBBPz  '@$JH]'L +!5'3>BrwP @ JH]'L+3'3#'X>ԠBBPN.@+J]'K]'L+3533#NBBBnP-N /@,J]'K]'L +35353#NBBBfPvN /@,J]'K]'L +35373#5NBBBPN /@,J]'K]'L +35353#NBBBqP1@J]'L+3'53#NנBBhPSi@J]'L+3'3#N<ܠBB xP CJKPX@](K]'L@e]'LY+3'353##N;զBBwP @ J]'L+3'3#5P>BBPa- @ J]'L+3'3#'N<٣BB$P1"1@J]'L+3'73#5N,CC1P"@J]'L+3'73#N,éBBn2P&#@ J]'L+!''73-ȠB/UP& @J]'L+3'753#N(ȠBBk4KsP( *@'Je]'L +!5#'7330B/P&"@J]'L+!'3.hB2.^P1@J]'L+3'3#N8CC#i$P #@J]'L+3'3#]:kBB!P&@J]'L+3'3#N4ҢBB&i/P  @J]'L+3'753#P:˭BBy"]Py @ J]'L+3'3#5'N4ҢBB%iP' #@ Je]'L+3'33##_8BB#e(PF%1!@J]'L+3'73.CS3P'$@!Je'L+!#'73/n0P.&@#JH]'L+!'73'ɗB7q2*P% '@$JH]'L +!''753-ɠB2P% '@$JH]'L +!5'73)ɠBrx3sP% '@$JH]'L +!'73*ɠB93P1!@J]'L+373>CvGP@J]'L+373#=BBuCP%@"J^'L+3733>mBvnP @ J]'L+3753#=BBu9?P @ J]'L+3773#5>BBvzP @ J]'L+3753#>BBv!0P@NKJKPX@](K]'L@e]'LY@ +!#5373}æBTnBPNKJKPX@](K]'L@e]'LY@ +!#533vBBPN LJKPX@](K]'L@e]'LY@ +!5#533BOBPN LJKPX@](K]'L@e]'LY@ +!'#533B-B#P1"@J]'L+3573:CP#@ J]'L+!739B|#P!@J]'L+!'73:mBxcSP $@!J]'L +!7539B"@XP *@'Je]'L +!5#733:BP $@!J]'L +!773:B2P%1"@J]'L+3'73.C+1&P'#@ J]'L+!'73/B/0$P%!@J]'L+!'73-jB21 P% $@!J]'L +!'7753/B͠/P%"@J]'L+!573.;Bi1P" *@'Je]'L +!#'733Ȥ0BF-(P"1!@J]'L+3'3UI:L!!>(:EA=1F3L4]#o?"%e/##%0/,.4 [ 3+swjq4N^C^pv^RZY^J1W^K/e^M=^p1Ol^Ql^LD0J dD@U]M +D!!_JGT('dD@U]M +D#5(PTx4dD@)U]M +D#53#5(PP^a =dD@2 JU]M    +D#.'5##.'5126. O126. "V 99 "V 99 d^L EdD@:~gW_O      +D2#"&546#"&'33267QHJK63.'9Lh)'d^ 2dD@'W_O    +D2#&&#"#66JK62.'97QH>)'0661<6708=;9##::B "B "X9K0 ۰3+W8J/ ڰ3+dGM< 3+dF 3+HHQ 3+lmLD 3+ f dD@U]M +D!5!@@1"3NPQ&q q3+0I 3+h@&dD@U]M +D%5!GGo0+'7%=:dD@t +D#L@08 *dD@gW_O +D2#52654#51<<1 8822727N&IdDK PX@nU^N@U^NY +D!53353BBڪnnC*dD@eU]M +D!5!!5!z ȓ^CO;dD@0JW_O!!"" +D4632632#4#"#4#">0661<6708;9##::B "B ";f 0+77''7f*<;+<<+;<*;+<<+;<*;;*<@@b*dD@gW_O +D463"#52654&&?E:D;#/2$-#03&,02 ڰ3+`^)C8^v&PIdDK PX@oU]M@U]MY +D!#5!#BBnn0"24x 3+]FdDK PX@oU]M@U]MY +D3#5#]Bx5=4>Q% 0dD@%JH GU]M +D7355#}d}}d\>>\\>>]%dD@Ht +D5#7# ;\\;x__xe '/7?GKOW_gowױdDKPX@6 e 754 e  9 8  g;:g=<gA@g?>e!C B#g%#E$D"+#"g)'G(F&*'&g/-+H*,+*g20,..,U20,,.^K3J1I.,.NKPX@54  ~6 e 7 g  9 8  g;:g=<gA@g?>e!C B#g%#E$D"+#"g)'G(F&*'&g/-+H*,+*g20,..,U20,,.^K3J1I.,.N@54  ~/-+&+-&~6 e 7 g  9 8  g;:g=<gA@g?>e!C B#g%#E$D"+#"g)'G(F&*'&g+H*,+*g20,..,U20,,.^K3J1I.,.NYY@ɤyxqpiha`YXQPLLHHA@9810)(!  }{xyuspwqwmkhoioec`gag][X_Y_USPWQWLOLONMHKHKJIEC@GAG=;8?9?530717-+(/)/%# '!'     L +D53#!5#53%53"5432"5432#"5432"5432!"5432"5432!"543253!53%"5432!"5432"5432!"5432"5432!"5432"5432#"5432"54325353!533353f_gLO;NQ6_5>y|b;g566fz.6ff6f66p.F3VF.p6gg666NP1dD@& JU]M +D#5667&&'5I6886 ., D 3  2S?&3+d^H BdD@7~gW_O "" +D6632#&&#""&54632QHJK62.'9e)'d!_ 0+77''7_*31/12*31/1K*21/13*21/1P0dD@% JU]M +D.'5>73E6886 ., D 3  2P1dD@& JU]M +D#5667&&'5I6886 .,( D 3  2H%dDK PX@ ! JKPX@ ! JKPX@ ! J@ ! JYYYK PX@U]MKPX@~U]MKPX@U]M@~U]MYYY@%$ +D#5667&&'5>73#&&'#6886 ., D 3   3( D 3  2@BB@ B@S?&3+qN[j#dD@  Gt +D37''7'7#F >F3883F>&F"B 0*@@*0 B"@+JdD@? JgW_O*($"  +D2632#"'#"&54632654&#"4&#"326S891<<1871<<  5  ''7228((8227iT_\dDKPX@noU^N@U^NY@  +D#7#73_"3{"3xCxC 1dD@&W_O    +D"&'332673*F#k)F3_]6>7=dXK 1 13+q, dD@U]M +D!5!,Xq3,  3+_4dD@)Wg_O#"#" +D#".#"#66323267 ]G9gdg9<93 ]H8fdh9<9D<!C=!~O 2dD@'W_O    +D2#&&#"#66*F#k)F3O_]6>7=dX%.dD@#JHGU]M +D!55!}}za>\\>&S0+'77Bv"v"@?LA@?LhT%dD@GU]M +D#'73{"C?KNP0dD@% JU]M +D.'5>73E6886 .,N D 3  2H%dDK PX@ ! JKPX@ ! JKPX@ ! J@ ! JYYYK PX@U]MKPX@~U]MKPX@U]M@~U]MYYY@%$ +D#5667&&'5#.'5366736886 .,{ D 3   3( D 3  2@BB@ B@l'LMMM3+3+u'@U]M+!!NAr.L3+rL3+Cw# !dDK(PX@  J@  JYK(PX@Wg_O@+~~Wg_OY@ !!    +D"&5463256673"&54632 `7uC S# T#Uw# !dDK(PX@ J@ JYK(PX@Wg_O@,~~Wg_OY@ !!    +D2#"&546#&&'52#"&546}Z *7,##S #T C\^)dD@ Jt +D#&&'#5>72$rK<^PWZ;*gh\26 // &))&S0+'77'I"v"vSL?@AL?@h^%dD@HU]M +D#'73"{^K?C idD@ JKPX@nhW_O@hW_OY@ #+#" +D#363232654&'7#".#"#>. #/(((0:0$7-)'-?m, 9*/6($l^%dD@HU]M +D37#{"C?KN2dD@'eW_O"" +D5!32673#"'%1(%39LDd%A.#"/ENRlT%dD@GU]M +D3'#"{K?C< ,dD@!JGW_O$! +D4#"56632'66/ .86+,"%1;4.(I7,2'4dD@)JgW_O$. +D"546654&&546654#"'6632,W !3     H`6dD@+Wg`P  +D"#"&5533266333RI&5=@4DX8659>^R'JJ^ 7 #/UdD@Jg W  g _O%$ +)$/%/##    +D"&54632'2654&#""&54632!"&546322>?11@?2 "! ^;21;;12;1 !! \F#.UdD@J,Jg  W  _O%$+)$.%.##  +D"&'#"&546326632%27&&#"2654&#"s(67$2A?4%65)2?3.(($"%% +*+\,-?50C)!-@45!3E"!((('D!$TlH2dD@' JU]M +D667#&&'55,"22",H #44# rv| #/dD@$gW_O$$$$$" +D4632#"&4632#"&74632#"&.`H2  0+''7'77''7'7755#47!75#45 45#56!65#46a55#57!75#55!55#57!75#55ACdD@8 gW_ OAA><86$$"$$$$$ +D>3232>3232>32#&&#"#".#"#".#"6+ *)$$), 4;5(&,#&,,%#,#C?)********2: 80??2:cDC #//dD@$U]M +D4673#&&%#654'34673#&&%#654'32002200220022002:0@>2: 80??2::0@>2: 80??2:3 3+hFG}l l3+h|GEl l3+ G~|l l3+hpFG)l l3+lkGIl l3+l_G l l3+}(zFgRlG l3+3+ |FGSl l3+ QGPl l3+q(oBgXlG l3+3+^lCGZYl l3+hdGl l3+hzGl l3+hoGl l3+ip  3+4'O(dD@W_O"$ +D#.#"#6632OB4MZ,EwNA bU% (+UP H]/adD@V+J*IHGggWg_O$$$$$$$" +D&&#"56323267#"&&&#"56323267#"& "("2( $(#1' "(!3( $(#1'Q :$ :#v :$ 9$hxGl l3+lxBGl l3+lbBGl l3+"BGl l3+alBGal l3+hdFGl l3+l|BGl l3+ifBGl l3+lBGbl l3+lsBG{l l3+hzFGl l3+lpBG~l l3+ |FGl l3+hgFGl l3+llBGl l3+lyBGl l3+"BG|l l3+lnBGl l3+flBG@l l3+d"BG>l l3+hzFGcl l3+@hCdDK-PX@ J@ JYK-PX@eW_O@"~eW_OY@ +D"&54633##5#"3267R0>@1O'G#" h59:3O&*hdFGl l3+hrFGl l3+lrCG P~l l3+hlG Ql l3+lG J{l l3+thFGNl l3+rhGG WLl l3+lBGWl l3+}lBG[zl l3+qlBG]Kl l3+wG @  3+  3+ 3+  3+ M3L 3+M L 3+K' ְ3+;[8%3dD@(gW_O$$$" +D326544#"&54&#"3"&54632! 1>=32$!!1;10=91$""0;2/=:t79dD@.  JGgW_O$$$" +D4&#"327#"&54632566?#  -9?11@78+&"1:10f0H] Ȱ3+kkK %dD@U]M +D%4673#&&%#654'3k2002)2002:0@>2: 80??2: @W_O$$$" +4632#"&74632#"&Q @W_O   +"&54632tu^ @ Jt $ +.'53@<q ,.u9877 r @Jt  +#5>7 19:$"  99 57u! 1@. JU]M    +566733566739g699g69u P,83 P,83~r!@ Jt +#&'#5>7\@#:;487;,*P& /:=, 57~r!@ Jt +#&&'5367-* h@#;86: 68 P& 5<,p &@#W_O "" +#"&'33267TFIQ86,)7BKJC-+Y7 "@gW_O$$$" +#"&546324&#"326A25?@41B7#"!"4<<33<<3  nt,@)gW_O#"#" +#".#"#66323267>,'$"4>.'$#BB!#AC""z@U]M +!!0E$$@!JHW_O%! +3267#"&54667Y-52+0""t-82,7, 5:qH^Q *8' Ұ3+IwFT$e5:ZdDKPX@noU^N@U^NY@ "$"+D#"&546336632#/h28c6dD@+Wg_O +D2#4&#"##532665956@ QdDKPX@oU]M@U]MY@ "2!+D#"543!2#"'&(()('n./33/.hjFGl l3+ltBGyl l3+lIGl l3+ |BGl l3+ulBGml l3+lBG[l l3+lwBGl l3+`lCGQXl l3+V .dD@#W_O ""+D#"&'33267QVVNB/4123@=6##$"ku':dD@/JUh]M##+D#7#"&55332677u4> %(? ! 'F)/)( >6{4dD@) JU]M+D#5&&5467576654&SWVT>RYVU1881>177^LL^_LL^A77CB77AhFGUcl l3+f; FKPX@oU]M@U]MY@ ""+#"5433</9g34;gg FKPX@nU^N@U^NY@ !+53632#)/"g;,2$D/;fE/;E/;/;/;x/;f/;;qFE3+E3+3+װ3+3+3+3+q3+L,>@>|3+|3+ l #'+/dD@ee  e     eeU]M  /.-,+*)('&%$ # #"!  +D3##5#53535!!5!5!!5!5!!5!3#3#3#00~;c;';c;';c;200000000'000000000000~;;hkFG/l l3+ldBGll l3+lBGfl l3+lrBGA|l l3+lBGMl l3+hdFGDl l3+]hFGHl l3+KhGGG6l l3+nhGGIYl l3+ gFGl l3+hgFGFl l3+hnGGl l3+hrFGHl l3+hzGl l3+^&MM nFGJl l3+lqGKl l3+l!GLl l3+hyGll l3+l~GNl l3+lGOl l3+ldG@l l3+^lFGP8l l3+lqFGQl l3+hzFGRl l3+VGU 3+l`FGUl l3+lpCGZl l3+haFGVl l3+hRtGWl l3+hoBGXl l3+l}BGYl l3+lyBG[l l3+lbBG]l l3+G9)&f 3+#3 >JKPX@ ]L@U]MY@  +#5>73!0= 79 59bj ʰ3+3 Al@-,JIKPX@_K_K_L@c_K_LY@ -,%&<# +&&#""&'3267#"&&'&&'&&'532654&&'.546632/R)>M'G08W3f 4$#06@)"  +g:FV*L23S1("-V>9'2$1L;7=+ J N8"(+8#!4@1I_K]L !! +"#53&&5466323#56654&2PV@;܆5?9mONm9?5:BWdS\wAA"y[Cj??jC[y"AAw\Sd0 @ JKL +3#57'53;;;;0  00 _ S 6@3eK^L    ! +!332#!373254&##BXh\fn7Xx=:QIOWD_1(S"#KPX@  JK"PX@  J@  JYYKPX@# e _ K_LKPX@' e _ KK_LK"PX@+ eK _ KK_L@1  eeK _ KK_LYYY@! ##  +2!3267#"&'##3366"!&&&Dd5YP3O*)P7nXX ~_?I>"bMn:xElbNgcX9GCQ[KQPKLPLO)3E}T?84Cad^IEYa ^rs]^qkR E@B  JIe]&K]*L +5!!5!#!'!6=K9UN77?w:>a/"+4@    JK PX@/n o   e _K ]L@-    e _K ]LY@,,,4,3/-+)%#""!! +5#3533253#5"##32654&##32654&#\\@"@?A=:(?%OF@7B\R=KRNhSBDXbbeehrOE?S &F7Nckbb;:;3J<8E(&@#U]M +7"&546323![Y+"(UC-,#  !N("0+'7'7S+G+G**(2+@(eU]M +"&54633#"33DHHD~~__~bDAAC*Z[*('2<@9eeU]M +"&54633#"335!DHHD~~__~bDAAC*Z[*w**(2   3+(02   3+(2(@%eU]M!"!+53254##532#(~__~~DHIC*Z[*DAAC(029@6eeU]M!"!+53254##532#5!(~__~~DHHD~*Z[*DAACw**(2 ZEE3+('2 3+NT.@+W_O +!3"&54632BP?NT1@.W_O +!3"&54632BPNT1@.W_O +!3"&54632BP NT1@.W_O +!3'"&54632BPNT-@*W_O +!3#"&54632BPNT.@+W_O +33"&54632NBP@NT1@.W_O +33"&54632NBPNT1@.W_O +33"&54632NBP NT1@.W_O +337"&54632NBPNT-@*W_O +333"&54632NBPNT 3+NT 3+NT*@'U]M+333#NBBNT 3+NT$@!U]M+333NBBww_<zC{ +-   X^ HA<>?15A,(,')<2 )B( Ht <1<Y<0<-<<?<7<,<1<2 H <2<8<2 :ax=a,aa=aS(ka aaa =]a =na%3, ZX J6<&IPt I<&(1.gU7g747Xg7jUNUUUjU]7gUg7U3ijO '|'| <2 H<[< <;<';D@1e (<2B(@17<2^^(oU7 H^%x '" qx=,a,a,a,aS'S(SSa = = = = =<@ =ZZZZ6]awU1.1.1.1.1.1.`.747474747E]7jU]7]7]7]7]7<2]7jOjOjOjOgU1.1.1.x=7x=7x=7x=7ag7i7,a47,a47,a47,a47,a47=g7=g7=g7=g7ajj SSSS(S(d(NkaUU PE aA aU a U ajUajUajUajU =]7 =]7 =]7=6naUna>naG%33%33%33%33, i, i, iZjOZjOZjOZjOZjOZjO  66<&'<&'<&'FU<]1.q`. =]7%33((y(((,((((AA H:;3Za aE,a<&a =S(ka`aa+# =a]a:$, 6$3J$5&S6g7+jUZReOg7wU\6+7jUS7ZRUoU#6]7 ]O7i7 eO7'O8ZeO]7eO8,a  a=%3S(Sa jap agaa a,aVL&bbjaaa =a]ax=, p $3JaP aaZaaya1.W9@UUE47!UUUBU}U]7pUgU76xUeJUU URUDU/47j U73NJvUj UrUaU      6(((  g g A<xMH1''6(6'HA7<-<!L<5A6_&k2> >>#>0Ae^ ^^^M< d)) o<X aU1.M8=h7 ZO,ab47U z aU<a U aQUK $5O=]7{{=G75=7=:<7a3aUgR eagUaUL&!a-UjaUj  oaU/aU a_U =7x=7, 66w(^ PmJP^JajUQQS(Va0UKamUaUPeJaUS(1.1.q`.,a47;43;43VL&!H#bUbU =]7=]7=]7yp p p PeJaUZa Ux&Jg>g7>6#)&y#&[aU=7 M5+J1.1.1.11.1.1.1.1.1.1.1.,a47,a47,a47,a47,&4,a47,a47,a47S(<S(N =]7 =]7 =]7 =]) =]7 =]7 =]7=h7=h7=h7=h7=h7ZjOZjO ZO ZO ZO ZO ZO666i7@@>CCC> , ig  gagU{ZdRxx=7* g3g7\6,<;L6=:U\ZS"kaUZjU=3=M7 gUna%/-:$ei@ i, %Z6<&'H#H7":0H#!$KUP+A H aa=7aaU aalU1.S =]7ZjOZjOZjOZjOZjO1.1.q`.=g7=g7ka =]7 =]7H# aa=7=g7aaajU1.1.,Q47,a47SS =]7 =]7nWnaTZjOZjO?&aja_7:T2<&'1.,a47 =]7 =]7 =]7 =]76}U77x=7 , 3'  `,a47=g7n  61Qg7gUgU!0g7g74343+X7g6g7>7jQjUjU ZR@$z^UUQQUjjUxU]7`786UUZRZ/U/U3iij ]eQ ''  7 =@UX->7}U Ug7 777^^U[UNUss77 7  k7L g !! ((((y(((BHBH(( (J77!X NNNNNNN((g ((K(K((((( H(((((((A!7! N2<6=]7e=7aV,0Q ]77=7]agUx=aU]xx=x =g7   `3@  ;TVT$V!V[2VVjVz; #^^^4'9z;z;VTQj&j( '!,V TVV5C=? ?i?i'(??U?N???(&??i:]mm5$2!7$o$o!:>$8[7`77$8&&7 3`5JH 7Q#$f3 73J7Q3$fQgg7XjgZi"gU7J*@$Zg T ] gUg7X 7U(UjUgU(3'1.g7g747+!3N!jO!78$Y$? $5577`7`577$#7! 55J22`D $agUagUagUx=7ag7ag7ag7ag7ag7,a47,a47,a47,a47,a47aX=g7ajQajUaj%jajUSSkaEkaUkaU aL  a aaUaUajUajUajUajU =]7 =]7 =]7 =]7]agU]agUnaUnaInaIna%33%33%33%33%33, i, i, i, iZjOZjOZjOZjOZjOXX    JJ6<&'<&'<&'jUi 1.FUg7g7g7g7g7g7g7g7++++++}} jUjUjUjUjUjUjUjU09ZNZGZZZZZZXIhhjk]7]7]7]7]7]76OeOeOeOeOeOeOeOeOOc888888885Eg7g7++jUjUZZR]7]7eOeO88g7g7g7g7g7g7g7g74>(*44jUjUjUjUjUjUjUjU'&/%88888888;;!g7g7g7g7g7g7g7GAGQqDvjUjUjUjUjUsp1;?aAAQvZZZZZZSSAAQveOeOeOeO]O]OeOeO66A{A{A88888\-S/h&AM+<('g ,H' H^^^mo$$X o!<$<3<8U< AS <<< < =`% x=<O@1>!   ] na1.iavUa/U<&'= $  aU7R5(e(i(Z(FF H H H((( H2 Q Qsm|g7g7g7g7g7g7g7g7ZZZZZZZZeOeOeOeOeOeOeOeOZZZZeOeOeOeOba[4444}WlNXllWkXkk..44....)&a2UpjaU2CakUaUaUAV<aaZ=\ zF1aB O1+#n#T}}xk kak ia  =C=]T  ==J-9^ZZW-),V4 \S9S9 \\p7aagfl#R L&=ak, !^=,aS(Z aa:U\65!!433UFF ]77UPEF+iU(-.NO(......! U YUt57gf g77 B' ggUK57UPU UUUAW5UJ0UUU vUgiwU:VP51.47#jUjOZZUH3 J......FJF FJF JJJHJJJDJJJP/P/P/P/P/WJWWJ#%#%####%#%##%#JJJJJJJJoJoJoJoJoJoJx0x0x0x0x0x0x0x0x0x0x00JJx0JJJJ))))))WE     TETETETETETETETETETETE35E.2]3aS(_{A"A"#-,Z ==Ka=aa Ta = =8=#3&0KR " `" V a aC==rSJ.5E7b7Uyz X1##-ZRoP":c 1UD7LUe>TxU]7w57E+!HuUiUU7]7\6q+B 7a|bfaUUwU=/ QJ $F"A  ahx2 a aa =av&$(aL6ka[8  11JC  W Wo 1jgD7jUA6KO+X-O<e.:6N b5zUiUiU,,C-6CC55oP"WFUPUx fiPiPT'G/rryiPg77[77`7777! ~"g#7 AH7+&<-<<?<7M:<2K6",8/;?8 <1?/<1#"#I#/#'##0#(# #%#"^^%^^^ ^^^^^^^%^^^ ^^^^^%d%J[B %60%%%^^%^^^ ^^^^^^6XDODva]<'L;55H54=5<564 HB(5d]{>>5'')45W   ) H##<E2^#,xx>>5'<f=5O5;2<2<2F$B H L+ J')H545apDCfL:1#Cz H'MPMMPM('BB(B( ((>('Z<89<556q qBwtXXXXXXXm*;F U" p7a%"tR#R#xR#R#-R#R# lE 6)  ](7= caj7NR,lacTay*8(^D,NNNN "&"(&&#' NNNN""&&(&#'%'.%%%NNNN%'%%%""#""""'%'%%%??NNNN%GGGGG3%%%%%%%%"%%-****+NNNNH_)[sYWel0ddNOsNCXWddHl 1N0o:NCC0`&0HHXQdH@~&hHCU\&hllHr2t33}q^]afd@tr}qw ;kNQtEN~N~M5n;HI58Hu`V6fgL]Kn^b#3A"d+#0%S6S[.Ol<a(J(Z(Z(Z(Z(Z(Z(Z(Z(NNNNNNNNNNNNNNNTTTT0x0@x< | ` H $P`D04@$\XL,d0ph !"@#@#$%&4&t'8'(@))*+D+,d,-d-.<.//\/0t0t012L3$3355678@8899:l:;X<L>?4?x@XADBCC<C`CCCCDpDDDDEE<E`EEF8F\FFFFGGLHH8H\HHHI8J\JtJJJJJL<LTLlLLLLLLMMMNNN4NLNdOOOOPPP4QQQ@QXQ|QQQQRR$R<R`RxRRRRST4TXTpTTTTUVV8VPVtVVVVWWW4WXW|XXY Y$YHY`YYYYYZZ ZDZ\ZtZZ[[@[X[p[[[[\T\\]]]0]T]l]^(^__0_T_l__`abbb0bHblbbbbbcc,cPchccccd4dee eDe\eeeeefffgg0gTglgggghh,hDhij|ll<lTlxlllm,mmn@noopppqrrr@rdrrrrss s0stt,t<tLttuu|uuv8vHvvwPw`wpxTxdyyyzz z8zPzhz{x|P|}~H~8H HDd\t`dt 4XTdtP`p4dX|D D\P$l|p@hD\`x 0@Xh0@Xp x,Ph8|$ \|,|$H0@P<0¬LÜhhhhhhhhhhhhhh $ $<TΜ<Ф8\tь0X֔נ0لڸۨXhx߰` D\Ld4`4@DH(`4 d(XL\Xhp| p 8   `  , (8Hl8Pt 4Xp,DhL8H,<@| , !t""x"##$&(&@&X&|&&&&' '0'H'l''''( (0(H(l(((() )$)<)`)x))))**,*P*h****++,+D+\+t++++,,(,@,d,|,,,--(-@-d-|----. .$.<.T.x....//,/D/h/////00(0L0d0|1 123L44567D7779 : :;,;>?@AA8AABlBCDxEF FGHLHIJKXKhKxLLLMNO\PPPQR`RSTHTUVPWLWX@XPXYZ\[0[\d] ]^ ^$^^^__<_T_l_____``,`D`h`````aa4aXapaaaabbb<bTc ddddeee4e`eeeeeff(f@fggghh hDh\hhhhhii4iLipiiiijj$j<j`jxjjkPkll4lnop|pppppqq4qLqpqqqqqrr0rttuvwxyzz{|\|}H~~~L|d@$<l(8t`H XDdd,LpT$\@p4@ 8`x4@P <pHDx ø Dhƌư@dtDŽǔǤT(tɔɤɴ,|ʨ(H˄˘˼(L̘@͔hΈΨθHpϘϸ8|PѼ |Ҍ(8HlӐӠԐԸ`נD٨۔@ܼ(8H<Ld|(pL p,\\XT|P8x ,Pt(Lp4X| 0Tx,Pt(Lp$Hl Dd$Ddhp0P $    (  8xT,,d T!x"#$%&'()*+p,@,d,,,,--<-`----..8.\....//4/X/|///0 000T0x00011,1P1t111122(2T2t222233(3585P5h5555566(6L6x666777@7d7|77778 8$8<8T8x888899,9D9h9999::8:P:t::::;;;4;L;p;;;;<<$<<<`>,>P>h>>>>>??<?\?????@ @$@H@l@@@@@A A8A\AtAAAABBB4BLBpBBBBCC$C<CTClCCCCCDD DDD\DtDDDDDEE(ELEpEEEFF$F<FTFlFFFFFG$GLGtGGGGGHH,HDH\HHHHIIDIlIIIIIJ J$J<JTJxJJJKK<KdKKKKKLLL@LdLLLMMM4MLMdM|MMMMNN8N\NtNNNNNOOO@OdOOOPP,PPPhPPPPPPQQ(Q@QXQpQQQQQRR4RPRlRRRS S8SdSSSTT(THThTTTTUU@UpUUVV0V`VVVVVWW,WHWtWWXX0X`XXXXY Y$Y@YXYtYYYZZZ|[[[$[\\4\T\l\\\\]]4^^___```0`H`l```abc\ctcccccddd@dddddefffg g(g@g`gggghhXhhiPijjPjhjkk\kl$llmm n0noDooppqqrrrrss8su v@wpxLyz{4{} }~D`\T(d$h\l@D<hHh$P\44 8Ph(@Xp0H`xdt\XHD8`0p<0\XPlT0Lè0Ĵ@@ ȬLT˸\͘ͰϨ<ѬPdӸՔttT\ܠ0ݤ\ ߰d$xD`8TdtHhDD,D\tl|xd (l $(x$<\   8  P   ( LT(LX4$ , !|"D"d"#L#$t%d&&'(x)4)****+,,,,D,\,t,,,,,--,.l011(1H1h111112$2D223|44 4@4X4x445l55566(6H6h666667<7788(8@89 9@9999::$:<:T:t::;;(;;;;<<0x>??(?H?h????@@@B`BC@CDLDdDDE@EXExEEEFFG\G|GGH H$HDHdH|HHHIxIIJJJJKKKlKKKL L$LLLLMMDMlMMMN NO@PPRXSHT`TxTUlVVWXXYZDZ[|\\\]^8^^__`dabDbd@de8fpfghi\ilj jkhl0m nnooopDpqXqs tttu@uvwtxxxyzt{0{||}$}~`t hp T@(d$0\P@<,,<`8@DČPƘ<Șɤˀ̴͸|p4XҔӬԄՠּ \۸Pߨ߸|\l$4Tt@d$t0Xd<x`|4T ,<\|<\|<\|4Tt<\|<\D4L0$Xt<  , T  T    X\h d|0h4X|x|Hlx0Pp 8  ! !D"|#\%%4%&&$&D&d&&''\'t'(X),)x)))**(*@*d*|***++,,,l,---x--..\//00$0$0$0$0$0$0$0$0$0$0$0$0$112024H45667@7`78x889<99:<< ^ <  4nCopyright 2015 Google Inc. All Rights Reserved.Noto SansRegular2.000;GOOG;NotoSans-RegularNoto Sans RegularVersion 2.000;GOOG;noto-source:20170915:90ef993387c0; ttfautohint (v1.7)NotoSans-RegularNoto is a trademark of Google Inc.Monotype Imaging Inc.Monotype Design TeamDesigned by Monotype design team.http://www.google.com/get/noto/http://www.monotype.com/studioThis Font Software is licensed under the SIL Open Font License, Version 1.1. This Font Software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the SIL Open Font License for the specific language, permissions and limitations governing your use of this Font Software.http://scripts.sil.org/OFL2   !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`a  bcdefghjikmlnoqprsutvwxzy{}|~    !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~                           ! " # $ % & ' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; < = > ? @ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ _ ` a b c d e f g h i j k l m n o p q r s t u v w x y z { | } ~                            ! " # $ % & ' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; < = > ? @ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ _ ` a b c d e f g h i j k l m n o p q r s t u v w x y z { | } ~                            ! " # $ % & ' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; < = > ? @ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ _ ` a b c d e f g h i j k l m n o p q r s t u v w x y z { | } ~                            ! " # $ % & ' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; < = > ? @ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ _ ` a b c d e f g h i j k l m n o p q r s t u v w x y z { | } ~  NULLCRuni00A0uni00AD overscoreuni00B2uni00B3uni00B5uni00B9AmacronamacronAbreveabreveAogonekaogonek Ccircumflex ccircumflexCdotcdotDcarondcaronDcroatEmacronemacronEbreveebreve Edotaccent edotaccentEogonekeogonekEcaronecaron Gcircumflex gcircumflexGdotgdotuni0122uni0123 Hcircumflex hcircumflexHbarhbarItildeitildeImacronimacronIbreveibreveIogonekiogonekIJij Jcircumflex jcircumflexuni0136uni0137 kgreenlandicLacutelacuteuni013Buni013CLcaronlcaronLdotldotNacutenacuteuni0145uni0146Ncaronncaron napostropheEngengOmacronomacronObreveobreve Ohungarumlaut ohungarumlautRacuteracuteuni0156uni0157RcaronrcaronSacutesacute Scircumflex scircumflexuni021Auni021BTcarontcaronTbartbarUtildeutildeUmacronumacronUbreveubreveUringuring Uhungarumlaut uhungarumlautUogonekuogonek Wcircumflex wcircumflex Ycircumflex ycircumflexZacutezacute Zdotaccent zdotaccentlongs Aringacute aringacuteAEacuteaeacute Oslashacute oslashacuteuni0218uni0219tonos dieresistonos Alphatonos anoteleia EpsilontonosEtatonos Iotatonos Omicrontonos Upsilontonos OmegatonosiotadieresistonosAlphaBetaGammauni0394EpsilonZetaEtaThetaIotaKappaLambdaMuNuXiOmicronPiRhoSigmaTauUpsilonPhiChiPsiuni03A9 IotadieresisUpsilondieresis alphatonos epsilontonosetatonos iotatonosupsilondieresistonosalphabetagammadeltaepsilonzetaetathetaiotakappalambdauni03BCnuxiomicronrhosigma1sigmatauupsilonphichipsiomega iotadieresisupsilondieresis omicrontonos upsilontonos omegatonos afii10023 afii10051 afii10052 afii10053 afii10054 afii10055 afii10056 afii10057 afii10058 afii10059 afii10060 afii10061 afii10062 afii10145 afii10017 afii10018 afii10019 afii10020 afii10021 afii10022 afii10024 afii10025 afii10026 afii10027 afii10028 afii10029 afii10030 afii10031 afii10032 afii10033 afii10034 afii10035 afii10036 afii10037 afii10038 afii10039 afii10040 afii10041 afii10042 afii10043 afii10044 afii10045 afii10046 afii10047 afii10048 afii10049 afii10065 afii10066 afii10067 afii10068 afii10069 afii10070 afii10072 afii10073 afii10074 afii10075 afii10076 afii10077 afii10078 afii10079 afii10080 afii10081 afii10082 afii10083 afii10084 afii10085 afii10086 afii10087 afii10088 afii10089 afii10090 afii10091 afii10092 afii10093 afii10094 afii10095 afii10096 afii10097 afii10071 afii10099 afii10100 afii10101 afii10102 afii10103 afii10104 afii10105 afii10106 afii10107 afii10108 afii10109 afii10110 afii10193 afii10050 afii10098WgravewgraveWacutewacute Wdieresis wdieresisYgraveygrave afii00208 underscoredbl quotereversedminutesecond exclamdbl nsuperior afii08941pesetaEuro afii61248 afii61289 afii61352uni2126 estimated oneeighth threeeighths fiveeighths seveneighths cyrillicbrevecaroncommaaccent commaaccentcommaaccentrotateuni2074uni2075uni2077uni2078uni2000uni2001uni2002uni2003uni2004uni2005uni2006uni2007uni2008uni2009uni200Auni200BuniFEFFuniFFFCuniFFFDuni01F0uni02BCuni03D1uni03D2uni03D6uni1E3Euni1E3Funi1E00uni1E01uni02F3OhornohornUhornuhornhookuni0400uni040Duni0450uni045Duni0460uni0461uni0462uni0463uni0464uni0465uni0466uni0467uni0468uni0469uni046Auni046Buni046Cuni046Duni046Euni046Funi0470uni0471uni0472uni0473uni0474uni0475uni0476uni0477uni0478uni0479uni047Auni047Buni047Cuni047Duni047Euni047Funi0480uni0481uni0482uni0488uni0489uni048Auni048Buni048Cuni048Duni048Euni048Funi0492uni0493uni0494uni0495uni0496uni0497uni0498uni0499uni049Auni049Buni049Cuni049Duni049Euni049Funi04A0uni04A1uni04A2uni04A3uni04A4uni04A5uni04A6uni04A7uni04A8uni04A9uni04AAuni04ABuni04ACuni04ADuni04AEuni04AFuni04B0uni04B1uni04B2uni04B3uni04B4uni04B5uni04B6uni04B7uni04B8uni04B9uni04BAuni04BBuni04BCuni04BDuni04BEuni04BFuni04C0uni04C1uni04C2uni04C3uni04C4uni04C5uni04C6uni04C7uni04C8uni04C9uni04CAuni04CBuni04CCuni04CDuni04CEuni04CFuni04D0uni04D1uni04D2uni04D3uni04D4uni04D5uni04D6uni04D7uni04D8uni04D9uni04DAuni04DBuni04DCuni04DDuni04DEuni04DFuni04E0uni04E1uni04E2uni04E3uni04E4uni04E5uni04E6uni04E7uni04E8uni04E9uni04EAuni04EBuni04ECuni04EDuni04EEuni04EFuni04F0uni04F1uni04F2uni04F3uni04F4uni04F5uni04F6uni04F7uni04F8uni04F9uni04FAuni04FBuni04FCuni04FDuni04FEuni04FFuni0500uni0501uni0502uni0503uni0504uni0505uni0506uni0507uni0508uni0509uni050Auni050Buni050Cuni050Duni050Euni050Funi0510uni0511uni0512uni0513uni1EA0uni1EA1uni1EA2uni1EA3uni1EA4uni1EA5uni1EA6uni1EA7uni1EA8uni1EA9uni1EAAuni1EABuni1EACuni1EADuni1EAEuni1EAFuni1EB0uni1EB1uni1EB2uni1EB3uni1EB4uni1EB5uni1EB6uni1EB7uni1EB8uni1EB9uni1EBAuni1EBBuni1EBCuni1EBDuni1EBEuni1EBFuni1EC0uni1EC1uni1EC2uni1EC3uni1EC4uni1EC5uni1EC6uni1EC7uni1EC8uni1EC9uni1ECAuni1ECBuni1ECCuni1ECDuni1ECEuni1ECFuni1ED0uni1ED1uni1ED2uni1ED3uni1ED4uni1ED5uni1ED6uni1ED7uni1ED8uni1ED9uni1EDAuni1EDBuni1EDCuni1EDDuni1EDEuni1EDFuni1EE0uni1EE1uni1EE2uni1EE3uni1EE4uni1EE5uni1EE6uni1EE7uni1EE8uni1EE9uni1EEAuni1EEBuni1EECuni1EEDuni1EEEuni1EEFuni1EF0uni1EF1uni1EF4uni1EF5uni1EF6uni1EF7uni1EF8uni1EF9uni20ABcircumflexacutecombcircumflexgravecombcircumflexhookcombcircumflextildecombbreveacutecombbrevegravecomb brevehookcombbrevetildecombcyrillichookleftcyrillicbighookUCuni0162uni0163uni0180uni0181uni0182uni0183uni0184uni0185uni0186uni0187uni0188uni0189uni018Auni018Buni018Cuni018Duni018Euni018Funi0190uni0191uni0193uni0194uni0195uni0196uni0197uni0198uni0199uni019Auni019Buni019Cuni019Duni019Euni019Funi01A2uni01A3uni01A4uni01A5uni01A6uni01A7uni01A8uni01A9uni01AAuni01ABuni01ACuni01ADuni01AEuni01B1uni01B2uni01B3uni01B4uni01B5uni01B6uni01B7uni01B8uni01B9uni01BAuni01BBuni01BCuni01BDuni01BEuni01BFuni01C0uni01C1uni01C2uni01C3uni01C4uni01C5uni01C6uni01C7uni01C8uni01C9uni01CAuni01CBuni01CCuni01CDuni01CEuni01CFuni01D0uni01D1uni01D2uni01D3uni01D4uni01D5uni01D6uni01D7uni01D8uni01D9uni01DAuni01DBuni01DCuni01DEuni01DFuni01E0uni01E1uni01E2uni01E3uni01E4uni01E5uni01E6uni01E7uni01E8uni01E9uni01EAuni01EBuni01ECuni01EDuni01EEuni01EFuni01F1uni01F2uni01F3uni01F4uni01F5uni01F6uni01F7uni01F8uni01F9uni0200uni0201uni0202uni0203uni0204uni0205uni0206uni0207uni0208uni0209uni020Auni020Buni020Cuni020Duni020Euni020Funi0210uni0211uni0212uni0213uni0214uni0215uni0216uni0217uni021Cuni021Duni021Euni021Funi0220uni0221uni0222uni0223uni0224uni0225uni0226uni0227uni0228uni0229uni022Auni022Buni022Cuni022Duni022Euni022Funi0230uni0231uni0232uni0233uni0234uni0235uni0236uni0238uni0239uni023Auni023Buni023Cuni023Duni023Euni023Funi0240uni0241uni0242uni0243uni0244uni0245uni0246uni0247uni0248uni0249uni024Auni024Buni024Cuni024Duni024Euni024Funi0250uni0251uni0252uni0253uni0254uni0255uni0256uni0257uni0258uni0259uni025Buni025Euni025Funi0260uni0261uni0262uni0263uni0264uni0265uni0266uni0267uni0268 iotaLatinuni026Auni026Buni026Cuni026Duni026Euni026Funi0270uni0271uni0272uni0273uni0274uni0275uni0276 omegacloseduni0278uni0279uni027Auni027Buni027Cuni027Duni027Euni027Funi0280uni0281uni0282uni0283uni0284uni0285uni0286uni0287uni0288uni0289uni028Auni028Buni028Cuni028Duni028Euni028Funi0290uni0291uni0292uni0293uni0294uni0295 glottalturneduni0297uni0298uni0299uni029Auni029Buni029Cuni029Duni029Euni029Funi02A0uni02A1uni02A2dzliguni02A4 dzligcurltsliguni02A7 tcligcurluni02A9uni02AAuni02ABuni02ACuni02ADuni02AEuni02AFuni02B0uni02B1uni02B2uni02B3uni02B4uni02B5uni02B6uni02B7uni02B8uni02B9uni02BAuni02BBuni02BDuni02BEuni02BFuni02C0uni02C1uni02C2uni02C3uni02C4uni02C5uni02C8uni02CAuni02CBuni02CCuni02CDuni02CEuni02CFuni02D0uni02D1uni02D2uni02D3uni02D4uni02D5uni02D6uni02D7uni02DFuni02E0uni02E1uni02E2uni02E3uni02E4uni02E5uni02E6uni02E7uni02E8uni02E9uni02EAuni02EBuni02ECuni02EDuni02EEuni02EFuni02F0uni02F1uni02F2uni02F4uni02F5uni02F6uni02F7uni02F8uni02F9uni02FAuni02FBuni02FCuni02FDuni02FEuni02FF hookabovecombuni0374uni0375uni037Auni037Buni037Cuni037Duni037Euni03D0uni03D3uni03D4phi1uni03D7uni03D8uni03D9uni03DAuni03DBuni03DCuni03DDuni03DEuni03DFuni03E0uni03E1uni03F0uni03F1uni03F2uni03F3uni03F4uni03F5uni03F6uni03F7uni03F8uni03F9uni03FAuni03FBuni03FCuni03FDuni03FEuni03FFuni051Auni051Buni051Cuni051Duni1D00uni1D01uni1D02uni1D03uni1D04uni1D05uni1D06uni1D07uni1D08uni1D09uni1D0Auni1D0Buni1D0Cuni1D0Duni1D0Euni1D0Funi1D10uni1D11uni1D12uni1D13uni1D14uni1D15uni1D16uni1D17uni1D18uni1D19uni1D1Auni1D1Buni1D1Cuni1D1Duni1D1Euni1D1Funi1D20uni1D21uni1D22uni1D23uni1D24uni1D25uni1D26uni1D27uni1D28uni1D29uni1D2Auni1D2Buni1D2Cuni1D2Duni1D2Euni1D2Funi1D30uni1D31uni1D32uni1D33uni1D34uni1D35uni1D36uni1D37uni1D38uni1D39uni1D3Auni1D3Buni1D3Cuni1D3Duni1D3Euni1D3Funi1D40uni1D41uni1D42uni1D43uni1D44uni1D45uni1D46uni1D47uni1D48uni1D49uni1D4Auni1D4Buni1D4Cuni1D4Duni1D4Euni1D4Funi1D50uni1D51uni1D52uni1D53uni1D54uni1D55uni1D56uni1D57uni1D58uni1D59uni1D5Auni1D5Buni1D5Cuni1D5Duni1D5Euni1D5Funi1D60uni1D61uni1D62uni1D63uni1D64uni1D65uni1D66uni1D67uni1D68uni1D69uni1D6Auni1D6Buni1D6Cuni1D6Duni1D6Euni1D6Funi1D70uni1D71uni1D72uni1D73uni1D74uni1D75uni1D76uni1D77uni1D78uni1D79uni1D7Auni1D7Buni1D7Cuni1D7Duni1D7Euni1D7Funi1D80uni1D81uni1D82uni1D83uni1D84uni1D85uni1D86uni1D87uni1D88uni1D89uni1D8Auni1D8Buni1D8Cuni1D8Duni1D8Euni1D8Funi1D90uni1D91uni1D92uni1D93uni1D94uni1D95uni1D96uni1D97uni1D98uni1D99uni1D9Auni1D9Buni1D9Cuni1D9Duni1D9Euni1D9Funi1DA0uni1DA1uni1DA2uni1DA3uni1DA4uni1DA5uni1DA6uni1DA7uni1DA8uni1DA9uni1DAAuni1DABuni1DACuni1DADuni1DAEuni1DAFuni1DB0uni1DB1uni1DB2uni1DB3uni1DB4uni1DB5uni1DB6uni1DB7uni1DB8uni1DB9uni1DBAuni1DBBuni1DBCuni1DBDuni1DBEuni1DBFuni1E02uni1E03uni1E04uni1E05uni1E06uni1E07uni1E08uni1E09uni1E0Auni1E0Buni1E0Cuni1E0Duni1E0Euni1E0Funi1E10uni1E11uni1E12uni1E13uni1E14uni1E15uni1E16uni1E17uni1E18uni1E19uni1E1Auni1E1Buni1E1Cuni1E1Duni1E1Euni1E1Funi1E20uni1E21uni1E22uni1E23uni1E24uni1E25uni1E26uni1E27uni1E28uni1E29uni1E2Auni1E2Buni1E2Cuni1E2Duni1E2Euni1E2Funi1E30uni1E31uni1E32uni1E33uni1E34uni1E35uni1E36uni1E37uni1E38uni1E39uni1E3Auni1E3Buni1E3Cuni1E3Duni1E40uni1E41uni1E42uni1E43uni1E44uni1E45uni1E46uni1E47uni1E48uni1E49uni1E4Auni1E4Buni1E4Cuni1E4Duni1E4Euni1E4Funi1E50uni1E51uni1E52uni1E53uni1E54uni1E55uni1E56uni1E57uni1E58uni1E59uni1E5Auni1E5Buni1E5Cuni1E5Duni1E5Euni1E5Funi1E60uni1E61uni1E62uni1E63uni1E64uni1E65uni1E66uni1E67uni1E68uni1E69uni1E6Auni1E6Buni1E6Cuni1E6Duni1E6Euni1E6Funi1E70uni1E71uni1E72uni1E73uni1E74uni1E75uni1E76uni1E77uni1E78uni1E79uni1E7Auni1E7Buni1E7Cuni1E7Duni1E7Euni1E7Funi1E86uni1E87uni1E88uni1E89uni1E8Auni1E8Buni1E8Cuni1E8Duni1E8Euni1E8Funi1E90uni1E91uni1E92uni1E93uni1E94uni1E95uni1E96uni1E97uni1E98uni1E99uni1E9Auni1E9Buni1F00uni1F01uni1F02uni1F03uni1F04uni1F05uni1F06uni1F07uni1F08uni1F09uni1F0Auni1F0Buni1F0Cuni1F0Duni1F0Euni1F0Funi1F10uni1F11uni1F12uni1F13uni1F14uni1F15uni1F18uni1F19uni1F1Auni1F1Buni1F1Cuni1F1Duni1F20uni1F21uni1F22uni1F23uni1F24uni1F25uni1F26uni1F27uni1F28uni1F29uni1F2Auni1F2Buni1F2Cuni1F2Duni1F2Euni1F2Funi1F30uni1F31uni1F32uni1F33uni1F34uni1F35uni1F36uni1F37uni1F38uni1F39uni1F3Auni1F3Buni1F3Cuni1F3Duni1F3Euni1F3Funi1F40uni1F41uni1F42uni1F43uni1F44uni1F45uni1F48uni1F49uni1F4Auni1F4Buni1F4Cuni1F4Duni1F50uni1F51uni1F52uni1F53uni1F54uni1F55uni1F56uni1F57uni1F59uni1F5Buni1F5Duni1F5Funi1F60uni1F61uni1F62uni1F63uni1F64uni1F65uni1F66uni1F67uni1F68uni1F69uni1F6Auni1F6Buni1F6Cuni1F6Duni1F6Euni1F6Funi1F70uni1F71uni1F72uni1F73uni1F74uni1F75uni1F76uni1F77uni1F78uni1F79uni1F7Auni1F7Buni1F7Cuni1F7Duni1F80uni1F81uni1F82uni1F83uni1F84uni1F85uni1F86uni1F87uni1F88uni1F89uni1F8Auni1F8Buni1F8Cuni1F8Duni1F8Euni1F8Funi1F90uni1F91uni1F92uni1F93uni1F94uni1F95uni1F96uni1F97uni1F98uni1F99uni1F9Auni1F9Buni1F9Cuni1F9Duni1F9Euni1F9Funi1FA0uni1FA1uni1FA2uni1FA3uni1FA4uni1FA5uni1FA6uni1FA7uni1FA8uni1FA9uni1FAAuni1FABuni1FACuni1FADuni1FAEuni1FAFuni1FB0uni1FB1uni1FB2uni1FB3uni1FB4uni1FB6uni1FB7uni1FB8uni1FB9uni1FBAuni1FBBuni1FBCuni1FBDuni1FBEuni1FBFuni1FC0uni1FC1uni1FC2uni1FC3uni1FC4uni1FC6uni1FC7uni1FC8uni1FC9uni1FCAuni1FCBuni1FCCuni1FCDuni1FCEuni1FCFuni1FD0uni1FD1uni1FD2uni1FD3uni1FD6uni1FD7uni1FD8uni1FD9uni1FDAuni1FDBuni1FDDuni1FDEuni1FDFuni1FE0uni1FE1uni1FE2uni1FE3uni1FE4uni1FE5uni1FE6uni1FE7uni1FE8uni1FE9uni1FEAuni1FEBuni1FECuni1FEDuni1FEEuni1FEFuni1FF2uni1FF3uni1FF4uni1FF6uni1FF7uni1FF8uni1FF9uni1FFAuni1FFBuni1FFCuni1FFDuni1FFEuni200Cuni200Duni200Euni200Funi2012uni2016uni201Funi202Auni202Buni202Cuni202Duni202Euni202Funi2034uni203Euni205Euni206Auni206Buni206Cuni206Duni206Euni206Funi2070uni2076uni2079uni2090uni2091uni2092uni2093uni2094uni20A0uni20A1uni20A2uni20A5uni20A6uni20A8uni20A9uni20ADuni20AEuni20AFuni20B0uni20B1uni20B2uni20B3uni20B4uni20B5uni20B9uni20F0uni2117uni214Duni214Euni2153uni2154uni2184uni2C60uni2C61uni2C62uni2C63uni2C64uni2C65uni2C66uni2C67uni2C68uni2C69uni2C6Auni2C6Buni2C6Cuni2C6Duni2C71uni2C72uni2C73uni2C74uni2C75uni2C76uni2C77uni2E17uniA717uniA718uniA719uniA71AuniA71BuniA71CuniA71DuniA71EuniA71FuniA720uniA721uniA788uniA789uniA78AuniA78BuniA78C dieresisacute dieresisgraveuniFE20uniFE21uniFE22uniFE23uni03B1030403130300uni03B1030403130301uni03B1030403140300uni03B1030403140301uni03B1030603130300uni03B1030603130301uni03B1030603140300uni03B1030603140301uni03B9030403130300uni03B9030403130301uni03B9030403140300uni03B9030403140301uni03B9030603130300uni03B9030603130301uni03B9030603140300uni03B9030603140301uni03C5030403130300uni03C5030403130301uni03C5030403140300uni03C5030403140301uni03C5030603130300uni03C5030603130301uni03C5030603140300uni03C5030603140301uni03B9030803040300uni03B9030803040301uni03B9030803060300uni03B9030803060301uni03C5030803040300uni03C5030803040301uni03C5030803060300uni03C5030803060301Eng.alt1Eng.alt2Eng.alt3 uni1FCD02C9 uni1FCE02C9 uni1FDD02C9 uni1FDE02C9dotacutecarondotmacrondieresis tildedieresis tildeacute macrongrave macronacute dieresiscarondieresismacron tildemacron dotmacron dotmacron.capuni030103060308uni030003060308uni030103040308uni030003040308 uni1FDE0306 uni1FDD0306 uni1FCE0306 uni1FCD0306uni0514uni0515uni0516uni0517uni0518uni0519uni051Euni051Funi0520uni0521uni0522uni0523uni0524uni0525uni0526uni0527cyrillic_otmarkuni20BAuni1EFAuni2C6Euni1E9ETurnedauni1EFCuni1EFEuniA722uniA724uniA726uniA728uniA72AuniA72CuniA72EuniA732uniA734uniA736uniA738uniA73AuniA73CuniA73EuniA740uniA742uniA744uniA746uniA748uniA74AuniA74CuniA74EuniA750uniA752uniA754uniA756uniA758uniA75AuniA75CuniA75EuniA760uniA764uniA766uniA768uniA76AuniA76CuniA76EuniA779uniA77BuniA77DuniA77EuniA780uniA782uniA784uniA786uniA78DuniA790uniA792uniA7A0uniA7A2uniA7A4uniA7A6uniA7A8uniA7AAuniA7ABuniA7ACuniA7ADuniA7B0uniA7B1uniA7B2uniA7B3uniA7B4uniA7B6Aogonek.loclNAVEogonek.loclNAVIogonek.loclNAVUogonek.loclNAVLcommaaccent.loclMAHNcommaaccent.loclMAHTurnedeafii10103dotlessafii10105dotless deltalatinuni2C78uni025Cuni025Duni01DDuni025Aiogonekdotlessuni0237uni1EFBuni1E9Cuni1E9Duni2C7A subscriptjuni2C79uni0249dotlessuni029Ddotlessuni02B2dotlessuni03F3dotlessuni1D62dotlessuni1D96dotlessuni1DA4dotlessuni1DA8dotlessuni1E2Ddotlessuni1ECBdotlessuniA723uniA725uniA727uniA729uniA72BuniA72DuniA72FuniA730uniA731uniA733uniA735uniA737uniA739uniA73BuniA73DuniA73FuniA741uniA743uniA745uniA747uniA749uniA74BuniA74DuniA74FuniA751uniA753uniA755uniA757uniA759uniA75BuniA75DuniA75FuniA761uniA765uniA767uniA769uniA76BuniA76DuniA76FuniA771uniA772uniA773uniA774uniA775uniA776uniA777uniA778uniA77AuniA77CuniA77FuniA781uniA783uniA785uniA787uniA78EuniA791uniA793uniA7A1uniA7A3uniA7A5uniA7A7uniA7A9uniA7B5uniA7B7uniA7FAuni1EFDuni1EFFaogonek.loclNAVeogonek.loclNAVlcommaaccent.loclMAHncommaaccent.loclMAHiogonek.loclNAVuogonek.loclNAVf_ff_f_if_f_lf_if_llongs_ts_ta.sc aacute.sc abreve.scacircumflex.sc adieresis.sc agrave.sc amacron.sc aogonek.scaring.sc aringacute.sc atilde.scae.sc aeacute.scb.scc.sc cacute.sc ccaron.sc ccedilla.scccircumflex.sccdot.scd.sceth.sc dcaron.sc dcroat.sce.sc eacute.sc ebreve.sc ecaron.scecircumflex.sc edieresis.sc edotaccent.sc egrave.sc emacron.sc eogonek.scf.scg.sc gbreve.scgcircumflex.scgcommaaccent.scgdot.sch.schbar.schcircumflex.sci.sc iacute.sc ibreve.scicircumflex.sc idieresis.sc idotaccent.sc igrave.scij.sc imacron.sc iogonek.sc itilde.scj.scjcircumflex.sck.sckcommaaccent.scl.sc lacute.sc lcaron.sclcommaaccent.scldot.sc lslash.scm.scn.sc nacute.sc ncaron.scncommaaccent.sceng.sc ntilde.sco.sc oacute.sc obreve.scocircumflex.sc odieresis.sc ograve.scohungarumlaut.sc omacron.sc oslash.scoslashacute.sc otilde.scoe.scp.scthorn.scq.scr.sc racute.sc rcaron.scrcommaaccent.scs.sc sacute.sc scaron.sc scedilla.scscircumflex.scscommaaccent.sc germandbls.sct.sctbar.sc tcaron.sc tcedilla.sctcommaaccent.scu.sc uacute.sc ubreve.scucircumflex.sc udieresis.sc ugrave.scuhungarumlaut.sc umacron.sc uogonek.scuring.sc utilde.scv.scw.sc wacute.scwcircumflex.sc wdieresis.sc wgrave.scx.scy.sc yacute.scycircumflex.sc ydieresis.sc ygrave.scz.sc zacute.sc zcaron.sc zdotaccent.scuni2071uniA78FuniA7F7uniA7FBuniA7FCuniA7FDuniA7FEuniA7FFuni0528uni052Auni052Cuni052EuniA640uniA642uniA644uniA646uniA648uniA64AuniA64CuniA64EuniA650uniA652uniA654uniA656uniA658uniA65AuniA65CuniA65EuniA660uniA662uniA664uniA666uniA668uniA66AuniA66CuniA680uniA682uniA684uniA686uniA688uniA68AuniA68CuniA68EuniA690uniA692uniA694uniA696uniA698uniA69Auni0529uni052Buni052Duni052Funi1C80uni1C81uni1C82uni1C83uni1C84uni1C85uni1C86uni1C87uni1C88uniA641uniA643uniA645uniA647uniA649uniA64BuniA64DuniA64FuniA651uniA653uniA655uniA657uniA659uniA65BuniA65DuniA65FuniA661uniA663uniA665uniA667uniA669uniA66BuniA66DuniA681uniA683uniA685uniA687uniA689uniA68BuniA68DuniA68FuniA691uniA693uniA695uniA697uniA699uniA69Bafii10066.loclSRBuniA66EuniA67FuniA69CuniA69Duni0370uni0372uni0376uni03CFuni037Funi0371uni0373uni0377 uni03D0.altCfrakturHfrakturIfrakturRfrakturZfrakturuniA762uniA763uni212Cuni210Buni2110uni2112PiDoubleStruckuni211BTurnedFuni212B CDoubleStruck HDoubleStruck NDoubleStruck PDoubleStruck QDoubleStruck RDoubleStruck ZDoubleStruckItalicDDoubleStruckGammaDoubleStruckuni2107uni212Auni2130uni2131uni2133uniA796uniA798uniA79AuniA79CuniA79EItalicdDoubleStruckItaliceDoubleStruckItaliciDoubleStruckItalicjDoubleStruckgammaDoubleStruckpiDoubleStruckuni210Euni210FscriptescriptoscriptguniA794uniA795uniA797uniA799uniA79BuniA79DuniA79FuniAB30uniAB31uniAB32uniAB33uniAB34uniAB35uniAB36uniAB37uniAB38uniAB39uniAB3AuniAB3BuniAB3CuniAB3DuniAB3EuniAB3FuniAB40uniAB41uniAB42uniAB43uniAB44uniAB45uniAB46uniAB47uniAB48uniAB49uniAB4AuniAB4BuniAB4CuniAB4DuniAB4EuniAB4FuniAB50uniAB51uniAB52uniAB53uniAB54uniAB55uniAB56uniAB57uniAB58uniAB59uniAB5AuniAB64uni2095uni2096uni2097uni2098uni2099uni209Auni209Buni209CuniA770uniA7F8uniA7F9uniAB5CuniAB5DuniAB5EuniAB5Funi2E2Fzero.lfone.lftwo.lfthree.lffour.lffive.lfsix.lfseven.lfeight.lfnine.lfzero.osfone.osftwo.osf three.osffour.osffive.osfsix.osf seven.osf eight.osfnine.osf zero.slash zero.tosfone.tosftwo.tosf three.tosf four.tosf five.tosfsix.tosf seven.tosf eight.tosf nine.tosf zero.dnomone.dnomtwo.dnom three.dnom four.dnom five.dnomsix.dnom seven.dnom eight.dnom nine.dnom zero.numrone.numrtwo.numr three.numr four.numr five.numrsix.numr seven.numr eight.numr nine.numruni215Funi2189uni2155uni2156uni2157uni2158uni2159uni215Auni2150uni2151uni2152uni2080uni2081uni2082uni2083uni2084uni2085uni2086uni2087uni2088uni2089uni2042uni204Cuni204Duni2045uni2046caretuni2041uni2040uni2050uni2E36uni2E37uni205Cuni2E13uni2E16uni2E08downwardsancorauni2E0Euni2049uni2E2Duni2059uni2055uni2E10uni205Buni2058uni2027uni2043uni2E12uni2E18uni2054uni2E04uni2E1Cuni2E0Cuni2E02uni2E09uni2E20uni204Eonedotenleaderonedotovertwodotspunctuationuni2E19uni2E0Funi2047uni2048uni2E34uni2E33uni2E07uni2E06uni2E0Buni203Buni2E11reversedparagraphreversedquestionmarkuni204Funi2E01uni2E00uni2E05uni2E1Duni2E0Duni2E03uni2E0Auni2E21uni2E30squaredfourdotpunctuationuni2053uni2056uni2E1Euni2E1Funi2E1Buni204Auni2E39uni205Duni2E32uni2E38uni2E35uni2051twodotenleaderuni205Atwodotsoveronedotpunctuationuni203Funi2023uni2E3Cuni2E3Duni2E3Euni2E3Funi2E41uniA673 upwardsancorauni2E31uni208Duni208Ebrackhalfbottomleftbrackhalfbottomrightbrackhalftopleftbrackhalftoprightleftdoubleparenthesisrightdoubleparenthesisuni2E26uni2E27uni207Duni207Euni2E1Auni2010uni2011uni2E3Buni2E3Auni2E40uni2036uni2035uni2057uni2037uni2E42 braceleft.sc braceright.scbracketleft.scbracketright.sc exclam.sc exclamdbl.sc exclamdown.scguilsinglleft.scguilsinglright.sc parenleft.sc parenright.sc question.scquestiondown.scuniA92EuniA67Euni205Funi2028uni2029uni2061uni2064uni2063uni2062uni2066uni2067uni2068uni2069uni2060uni20B6uni20BCuni20BDuni20AAuni20B7uni20B8uni20BBuni20BEuni2127uni2135uni214Buni2136uni2052uni2138uni208Cuni207Cuni2137uni208Buni207Buni2031uni208Auni207AreversedSansSerifLsummationDoubleStruckturnedSansSerifGturnedSansSerifLturnedSansSerifYRotatedQuni2100uni2101uni2106uni2103uni2104uni213Buni2109uni2139uni203Duni2114uni2125uni214C prescriptionuni214Auni211Funi2108uni2120symbolforsamaritansourceuni2121uni2123 weierstrassuni02DEuni02E5_uni02E5_uni02E9uni02E5_uni02E5_uni02E6uni02E5_uni02E5_uni02E8uni02E5_uni02E5_uni02E7uni02E5_uni02E9uni02E5_uni02E9_uni02E5uni02E5_uni02E9_uni02E9uni02E5_uni02E9_uni02E6uni02E5_uni02E9_uni02E8uni02E5_uni02E9_uni02E7uni02E5_uni02E6uni02E5_uni02E6_uni02E5uni02E5_uni02E6_uni02E9uni02E5_uni02E6_uni02E6uni02E5_uni02E6_uni02E8uni02E5_uni02E6_uni02E7uni02E5_uni02E8uni02E5_uni02E8_uni02E5uni02E5_uni02E8_uni02E9uni02E5_uni02E8_uni02E6uni02E5_uni02E8_uni02E8uni02E5_uni02E8_uni02E7uni02E5_uni02E7uni02E5_uni02E7_uni02E5uni02E5_uni02E7_uni02E9uni02E5_uni02E7_uni02E6uni02E5_uni02E7_uni02E8uni02E5_uni02E7_uni02E7uni02E9_uni02E5uni02E9_uni02E5_uni02E5uni02E9_uni02E5_uni02E9uni02E9_uni02E5_uni02E6uni02E9_uni02E5_uni02E8uni02E9_uni02E5_uni02E7uni02E9_uni02E9_uni02E5uni02E9_uni02E9_uni02E6uni02E9_uni02E9_uni02E8uni02E9_uni02E9_uni02E7uni02E9_uni02E6uni02E9_uni02E6_uni02E5uni02E9_uni02E6_uni02E9uni02E9_uni02E6_uni02E6uni02E9_uni02E6_uni02E8uni02E9_uni02E6_uni02E7uni02E9_uni02E8uni02E9_uni02E8_uni02E5uni02E9_uni02E8_uni02E9uni02E9_uni02E8_uni02E6uni02E9_uni02E8_uni02E8uni02E9_uni02E8_uni02E7uni02E9_uni02E7uni02E9_uni02E7_uni02E5uni02E9_uni02E7_uni02E9uni02E9_uni02E7_uni02E6uni02E9_uni02E7_uni02E8uni02E9_uni02E7_uni02E7uni02E6_uni02E5uni02E6_uni02E5_uni02E5uni02E6_uni02E5_uni02E9uni02E6_uni02E5_uni02E6uni02E6_uni02E5_uni02E8uni02E6_uni02E5_uni02E7uni02E6_uni02E9uni02E6_uni02E9_uni02E5uni02E6_uni02E9_uni02E9uni02E6_uni02E9_uni02E6uni02E6_uni02E9_uni02E8uni02E6_uni02E9_uni02E7uni02E6_uni02E6_uni02E5uni02E6_uni02E6_uni02E9uni02E6_uni02E6_uni02E8uni02E6_uni02E6_uni02E7uni02E6_uni02E8uni02E6_uni02E8_uni02E5uni02E6_uni02E8_uni02E9uni02E6_uni02E8_uni02E6uni02E6_uni02E8_uni02E8uni02E6_uni02E8_uni02E7uni02E6_uni02E7uni02E6_uni02E7_uni02E5uni02E6_uni02E7_uni02E9uni02E6_uni02E7_uni02E6uni02E6_uni02E7_uni02E8uni02E6_uni02E7_uni02E7uni02E8_uni02E5uni02E8_uni02E5_uni02E5uni02E8_uni02E5_uni02E9uni02E8_uni02E5_uni02E6uni02E8_uni02E5_uni02E8uni02E8_uni02E5_uni02E7uni02E8_uni02E9uni02E8_uni02E9_uni02E5uni02E8_uni02E9_uni02E9uni02E8_uni02E9_uni02E6uni02E8_uni02E9_uni02E8uni02E8_uni02E9_uni02E7uni02E8_uni02E6uni02E8_uni02E6_uni02E5uni02E8_uni02E6_uni02E9uni02E8_uni02E6_uni02E6uni02E8_uni02E6_uni02E8uni02E8_uni02E6_uni02E7uni02E8_uni02E8_uni02E5uni02E8_uni02E8_uni02E9uni02E8_uni02E8_uni02E6uni02E8_uni02E8_uni02E7uni02E8_uni02E7uni02E8_uni02E7_uni02E5uni02E8_uni02E7_uni02E9uni02E8_uni02E7_uni02E6uni02E8_uni02E7_uni02E8uni02E8_uni02E7_uni02E7uni02E7_uni02E5uni02E7_uni02E5_uni02E5uni02E7_uni02E5_uni02E9uni02E7_uni02E5_uni02E6uni02E7_uni02E5_uni02E8uni02E7_uni02E5_uni02E7uni02E7_uni02E9uni02E7_uni02E9_uni02E5uni02E7_uni02E9_uni02E9uni02E7_uni02E9_uni02E6uni02E7_uni02E9_uni02E8uni02E7_uni02E9_uni02E7uni02E7_uni02E6uni02E7_uni02E6_uni02E5uni02E7_uni02E6_uni02E9uni02E7_uni02E6_uni02E6uni02E7_uni02E6_uni02E8uni02E7_uni02E6_uni02E7uni02E7_uni02E8uni02E7_uni02E8_uni02E5uni02E7_uni02E8_uni02E9uni02E7_uni02E8_uni02E6uni02E7_uni02E8_uni02E8uni02E7_uni02E8_uni02E7uni02E7_uni02E7_uni02E5uni02E7_uni02E7_uni02E9uni02E7_uni02E7_uni02E6uni02E7_uni02E7_uni02E8uniAB5B ampersand.scuni2129uni0308uni0307 gravecomb acutecombuni030Buni0302uni030Cuni0306uni030A tildecombuni0304 overlinecmbuni030Duni030Euni030Funi0310uni0311uni0312uni0313uni0314uni0315uni0316uni0317uni0318uni0319uni031Auni031Buni031Cuni031Duni031Euni031Funi0320hookpalatalizedbelowcombhookretroflexbelowcomb dotbelowcombuni0324uni0325uni0327uni0328uni0329uni032Auni032Buni032Cuni032Duni032Euni032Funi0330uni0331uni0332uni0333uni0334strokeshortoverlaycombstrokelongoverlaycombslashshortoverlaycombslashlongoverlaycombuni0339uni033Auni033Buni033Cuni033Duni033Euni033Funi0340uni0341uni0346uni0347uni0348uni0349uni034Auni034Buni034Cuni034Duni034Euni034Funi0350uni0351uni0352uni0353uni0354uni0355uni0356uni0357uni0358uni0359uni035Auni035Buni035Cuni035Duni035Euni035Funi0360uni0361uni0362acutegraveacute acutemacronuni1DFEuni1DFF brevemacroncombiningconjoiningmacroncombiningmacronlefthalfcombiningmacronrighthalf dottedacute dottedgravedoublecircumflexabovegraveacutegrave gravemacronuni1DD0uni1DC4 macronbreveuni1DC6 ogonekabove snakebelowsuspensionmarkuni1AB0uni1AB1uni1AB2uni1AB3uni1AB4uni1AB5uni1AB6uni1AB7uni1AB8uni1AB9uni1ABAuni1ABBuni1ABCuni1ABDuni1DE7uni1DE8uni1DE9uni1DEAuni1DEBuni1DECuni1DEDuni1DEEuni1DEFuni1DF0uni1DF1uni1DF2uni1DF3uni1DF4uni1DF5uni1DFBuni1DFCuni1DFDuni2DE0uni2DE1uni2DE2uni2DE3uni2DE4uni2DE5uni2DE6uni2DE7uni2DE8uni2DE9uni2DEAuni2DEBuni2DECuni2DEDuni2DEEuni2DEFuni2DF0uni2DF1uni2DF2uni2DF3uni2DF4uni2DF5uni2DF6uni2DF7uni2DF8uni2DF9uni2DFAuni2DFBuni2DFCuni2DFDuni2DFEuni2DFFuniFE00uniFE27uniFE28uniFE29uniFE2AuniFE2BuniFE2CuniFE2Duraboveusabove zigzagbelowuni1ABEdieresiscomb.scdotaccentcomb.sc gravecomb.sc acutecomb.schungarumlautcomb.sccircumflexcomb.sc caroncomb.sc brevecomb.sc ringcomb.sc tildecomb.sc macroncomb.sc ogonekcomb.sc overscore.scuni0342uni0343uni0344uni0345uni0483uni0484uni0485uni0486uni0487uniA66FuniA674uniA675uniA676uniA677uniA678uniA679uniA67AuniA67BuniA67CuniA67DuniA69EuniA69FuniFE2EuniFE2FuniA670uniA671uniA672uni1DDBuni1DDEuni1DDFuni1DE1uni1DE2uni0363uni1DD4uni1DD5uni1DD6uni1DD7uni0368uni0369uni0364uni1DD9flattenedopenaaboveuni1DDAuni036Auni0365uni1DD8uni1DDCuni1DDDuni1DE5uni036Buni1DE0uni0366uni1DCAuni036Cuni1DE3uni1DE4uni036Duni0367uni036Euni036Funi1DE6uni2C7D commaaccent2uni2C70uni2C7Euni2C7FuniAB65uniA7AEuniAB60uniAB61uniAB62uniAB63summationDoubleStruck.miruni20BFuni2E43uni2E44uniA700uniA701uniA702uniA703uniA704uniA705uniA706uniA707uniA708uniA709uniA70AuniA70BuniA70CuniA70DuniA70EuniA70FuniA710uniA711uniA712uniA713uniA714uniA715uniA716[[II-"-[[II-"-\\KK<-E-\\KK<<-<D-HH>>h-h-HH>>--[[II-"-;;,,*~a-2va-;;,,a-g-۰, UXEY KQKSZX4(Y`f UX%acc#b!!YC#DC`B-, `f-, d P&Z( CEcEEX!%YR[X!#!X PPX!@Y 8PX!8YY  CEcEad(PX! CEcE 0PX!0Y PX f a PX` PX! ` 6PX!6``YYY% CcRXK PX! CKPX!Kac CcbYYdaY+YY#PXeYY-, E %ad CPX#B#B!!Y`-,#!#! dbB #BEX CEc C `Ec*! C +0%&QX`PaRYX#Y!Y @SX+!@Y#PXeY-,C+C`B-,#B# #Babfc`*-, E Ccb PX@`Yfc`D`-, CEB*!C`B- ,C#DC`B- , E +#C%` E#a d PX!0PX @YY#PXeY%#aDD`- , E +#C%` E#a d$PX@Y#PXeY%#aDD`- , #B EX!#!Y*!- ,EdaD-,` CJPX #BYCJRX #BY-, bfc c#aC` ` #B#-,KTXdDY$ e#x-,KQXKSXdDY!Y$e#x-,CUXCaB+YC%B %B%B# %PXC`%B #a*!#a #a*!C`%B%a*!Y CGCG`b PX@`Yfc Ccb PX@`Yfc`#DC>C`B-,ETX#B E #B # `B `aBB`++"Y-,+-,+-,+-,+-,+-,+-,+-,+-,+-, +-),# bfc`KTX# .]!!Y-*,# bfc`KTX# .q!!Y-+,# bfc&`KTX# .r!!Y-, +ETX#B E #B # `B `aBB`++"Y-,+- ,+-!,+-",+-#,+-$,+-%,+-&,+-',+-(, +-,, <`--, `` C#`C%a`,*!-.,-+-*-/, G Ccb PX@`Yfc`#a8# UX G Ccb PX@`Yfc`#a8!Y-0,ETX EB/*EX0Y"Y-1, +ETX EB/*EX0Y"Y-2, 5`-3, EBEcb PX@`Yfc+ Ccb PX@`Yfc+D>#82*!-4, < G Ccb PX@`Yfc`Ca8-5,.<-6, < G Ccb PX@`Yfc`CaCc8-7,% . G#B%IG#G#a Xb!Y#B6*-8,#B%%G#G#a B C+e.# <8-9,#B%% .G#G#a #B B C+ `PX @QX  &YBB# C #G#G#a#F`Cb PX@`Yfc` + a C`d#CadPXCaC`Y%b PX@`Yfca# &#Fa8#CF%CG#G#a` Cb PX@`Yfc`# +#C`+%a%b PX@`Yfc&a %`d#%`dPX!#!Y# &#Fa8Y-:,#B & .G#G#a#<8-;,#B #B F#G+#a8-<,#B%%G#G#aTX. <#!%%G#G#a %%G#G#a%%I%acc# Xb!Ycb PX@`Yfc`#.# <8#!Y-=,#B C .G#G#a ` `fb PX@`Yfc# <8->,# .F%FCXPRYX +-o,:+?+-p,:+@+-q,:+>+-r,:+?+-s,:+@+-t,;+..+-u,;+>+-v,;+?+-w,;+@+-x,;+>+-y,;+?+-z,;+@+-{,<+..+-|,<+>+-},<+?+-~,<+@+-,<+>+-,<+?+-,<+@+-,=+..+-,=+>+-,=+?+-,=+@+-,=+>+-,=+?+-,=+@+-, EX!#!YB+e$PxEX0Y-KRXYcpB@ o_C/ *B@vfVJ6$ *B@{n^P@- *BA *@%@ @ @ *BA @@@@@@@@@ *D$QX@XdD(QXXDY'QX@cTXDYYYYY@xhXL8& *DdDD ttfautohint version = 1.7 adjust-subglyphs = 0 default-script = latn dw-cleartype-strong-stem-width = 0 fallback-scaling = 0 fallback-script = none fallback-stem-width = 0 gdi-cleartype-strong-stem-width = 1 gray-strong-stem-width = 0 hinting-limit = 200 hinting-range-max = 50 hinting-range-min = 8 hint-composites = 0 ignore-restrictions = 0 increase-x-height = 14 reference = reference-index = 0 symbol = 0 TTFA-info = 1 windows-compatibility = 1 x-height-snapping-exceptions = control-instructions = linphone-desktop-4.2.5/linphone-app/assets/fonts/NotoSans-hinted/NotoSansUI-Bold.ttf000066400000000000000000011364641376717241300305000ustar00rootroot00000000000000GDEF5( GPOS  GSUBF # `OS/2V~`cmapO'hcvt ''8fpgm6  . gasp# glyf|J_Xzheadw[z6hhea$ 7T$hmtxU%locaNf9%maxp x nameC postif prep#T5\rW"_< 4(   m  o pRT_\K33f GOOG X ^ Ju+-X5?R!R=\?XH?=HuNJyNN#dH7HBHuH?XXX-f`w{dwBhP^w^wHh^) 3V1N 3/JLV\\\)\Bqq}qB\\\y/B 7'h'RXJuRqhjd/RX=dm\X/;LH=qHu\9R . . Z=w{{{{*B9/^w^w^w^w^w^w    VVVVVVVV\\\\\qqqq\B\\\\\X\BBBBVVVw\w\w\w\\/1\{\{\{\{\{\w\w\w\w\BBq?qqBq^BqBhq}PqqcqmqBBB;B^w\^w\^w\w\HHcHSh^\h^\h^\h^\)y/)y/)y/ B B B B B B171717VVV^w\h^\qT Hu B`}D9{1^wBP3R^wN)\VmJ79-\qNBB)-\H\qN\B\BH\Fy\9\N))V\mB )F)m{q)}jwh^B9hq)`N`} {/^`^ww)N\V?m?NHRV\P\qN)L\7\m/\ ?{J\B1\\qqq}B`RRRJH??!{!qbu ??!RRu wbf#R#B\?))9/#J7f : ; Z C;D9 )Xd%qLXXVXX))hq}^^N T;-VyHTTq}) 3V xXhX))wo\{\wbLf 7o) )qm^w\ w )\wo\w\wjw1\hu))Tj/y/;/^qN RP% 7w?\w\)f/ q)T/om{m?{TBJLm?{JhBVVVV{v\XX/^qN99^w\^w\^w\NHJNNNm?{}?y/) V \\h\b\N9JND{XfwN\)//XqNVVVVVVVVVVV{\{\{\{\{{\{\{\BquBq^w\^w\^w\^w^w\^w\^w\wo\wo\wo\wo\wo\ B B1\- -11111 V)y/Z JHw\/ \\\{y/Xdw397PHB^w wo\ HhVNNy/ y/)J73179PPb79qNJ!!!fJu y \+ 'Vq^w\ B B B B BXVVVVw\w\P^w\^w\99 y \w\bhBVV{P\{\sq q^w\^w\HqH B B/^B\!m\17V{\^w\^w\^w\^w\{N)/\\w\/)\7` 3{\hq}3w\H\?f\\\XX\qNqNN\q}\\\BBBqB){=qBB\\^\+++//+\qqqqFyBy/B/3\7791\^wN\LqF\1 \\\//\/)mJBB``' 1-'T+T+!H,H,HH#+oo#++oo++T+T+++++1-dj+DDXXXXXXXL++oHu)))NVw[CNw====LLF)))9U6}NNwwc!YaV V5}/}V;cUmBYBF%T=TT'w=??BB???))?\?R?Z+ \)^w\w\m'h\f\\wV'1D9P9w\Bm )^\q}^w1\JwHwHu^w\}VXZ'yFDVqJT+'V3y)H?\?\?%Xu\\1oo+7NDN;b)VDd91m-uwm\qT'sqbmu'%ZhbhhbhXoHfh9Fhh1 `wfh wh\B/}y1/qBD/\)\qqBq\ 7V\\\qNqNXq?qBqN5^Z^RHHqB^uLFLF=^^^1#)RRRL-^^5u99JT```w\\\\\\{\{\{\{\{\d)w\BBBBqBq?qPPPqqqqBBBB^w\^w\^w\^w\HHHHh^\h^\h^\h^\h^\)y/)y/)y/)y/ B B B B B33V V 171717By/V-\-\-\-\-\-\-\-\{{qNqNqNqNqNqNNN{{BBBBBBBBHHBBBBB,BBBJ={{jj\\\\\\dd))))))))Lmmmmmmmmqq)-\-\qNqNBBB;B\\))mm-\-\-\-\-\-\-\-\     BBBBBBBB 3 3   ` ` X Xmmmmmmmm ; P   V j -\-\-\-\-\-\-\==BBBBBRF `BBBBBB?);))))yy));;ummmmm 7=!LRhNmHu)3+Zhh'b+JJT))w3wd? = : ? wHudX#f{mmb))s+jVFR?;?;fBhfqHVy/Z173wV\!)))HbfJy)} VVVVVNVRVNVNVFFV5V5VPV-VH-V%V%V%V'V/%VVV5V5V/)VPVLVLVLV^LVVVVVPVLVFVLVLLV/V9V?V?V??V5V5V5V5V55VLVLVLVLVLhVLVFVLVLVLLVVVVVVVVVXVVVV\V7V7V7V7V77VHVFVFVFVFFVVV9V9V99VVVVVLVVVVVLVLVLVLVPPV/V5V5VV)V/V'V%V%V%%VHV-VPV5V5-VFVNVNVRVNFVVVV-\-\-\-\-\-\-\-\BBBBBBBB))))))))BBBB)))) 93F3F3F3FdhR=R=RVRVRJRJRJ9# =` 9P uLXX# \`` ~ac67"#ou~  OP\_'=?EMWY[]}  " & / 0 4 : < > D ^ p y  !!!!"!&!.!N!T!^!!!"""""""")"+"H"a"e###!%%% %%%%%$%,%4%<%l%%%%%%%%%%%%%%%&<&@&B&`&c&f&k&o),m,w.!# bd78#$tz PQ]`>@ HPY[]_  & * 0 2 9 < > D ^ j t  !!!!"!&!.!M!S![!!!"""""""")"+"H"`"d### %%% %%%%%$%,%4%<%P%%%%%%%%%%%%%%%&:&@&B&`&c&e&j&o),`,q. ^IvedAeY @SQzKIzx?wZI we%" {ob`aa` kLP>:6&$&8F0(.@@<"$ IJ$%KLM`abVPQWXYRh X Y Z [ \ ]STUV     ;<=>r i,-03PQ45Z[@G[ZYXUTSRQPONMLKJIHGFEDCBA@?>=<;:9876510/.-,('&%$#"! , `E% Fa#E#aH-, EhD-,E#F` a F`&#HH-,E#F#a ` &a a&#HH-,E#F`@a f`&#HH-,E#F#a@` &a@a&#HH-, <<-, E# D# ZQX# D#Y QX# MD#Y &QX# D#Y!!-, EhD ` EFvhE`D-, C#Ce -, C#C -,(#p(>(#p(E: -, E%EadPQXED!!Y-,I#D-, EC`D-,CCe -, i@a ,b`+ d#da\XaY-,E+)#D)z-,Ee,#DE+#D-,KRXED!!Y-,KQXED!!Y-,%# `#-,%# a#-,%-,CRX!!!!!F#F`F# F`ab# # pE` PXaFY`h:Y-, E%FRKQ[X%F ha%%?#!8!Y-, E%FPX%F ha%%?#!8!Y-,CC -, %EPX ED!!EDY-,!QX d#d b@/+Y`-,!QX d#dUb/+Y`-, d#d@b`#!-,KSX%Id#Ei@ab aj#D#!# 9/Y-,KSX %Idi &%Id#ab aj#D&#D#D& 9# 9//Y-,E#E`#E`#E`#vhb -,H+-, ETX@D E@aD!!Y-,E0/E#Ea``iD-,KQX/#p#B!!Y-,KQX %EiSXD!!Y!!Y-,EC`c`iD-,/ED-,E# E`D-,E#E`D-,K#QX34 34YDD-,CX&EXdf`d `f X!@YaY#XeY)#D#)!!!!!Y-,CTXKS#KQZX8!!Y!!!!Y-,CX%Ed `f X!@Ya#XeY)#D%% XY%% F%#B<%%%% F%`#B< XY%%)) EeD%%)%% XY%%CH%%%%`CH!Y!!!!!!!-,% F%#B%%EH!!!!-,% %%CH!!!-,E# E P X#e#Y#h @PX!@Y#XeY`D-,KS#KQZX E`D!!Y-,KTX E`D!!Y-,KS#KQZX8!!Y-,!KTX8!!Y-,CTXF+!!!!Y-,CTXG+!!!Y-, T#T[XCPCT[X!!!!H+YCPCT[XH+!!!!YY-, T#T[XCPCT[X!!!I+YCPCT[XI+!!!YY-, #KSKQZX#8!!Y-,%%Ij SX@`8!!Y-,%%Ij QX@a8!!Y-, #Id#SX<!Y-,KRX}zY-,KKTB-,B#Q@SZXB TXC`BY$QX @TXC`B$TX C`BKKRXC`BY@TXC`BY@cTXC`BY@cTXC`BY&QX@cTX@C`BY@cTXC`BYYYYYYCTXBY-,Eh#KQX# E d@PX|Yh`YD-,%%#>#> #eB #B#?#? #eB#B-,CPCT[X!# Y-,Y+-,-@ [PZU?ZOZZXUYPXU0X@XPXXWPVU V@VPVVVTUUPTUpTT0T@TTTT0MMNUOPNU3NNKUJPIUIKUGdFU?FFFKULPKUKK?KKSPRU;RRPUQPPU@% F!3 U     U3U?~]}xxwsAvsAus#ts+swsss3U3Uyvz9qqqppwnnli#ki+ji6fiviigi3UU3U?yEńEUZjF_{{{rrhZgjggF fffYfifff eeied]@ZYcycc'cOb_bbba]3`_P_]"^]<]]dU3UU3U0UdUoTS++KRK P[%S@QZUZ[XYBK2SX`YKdSX@YKSXBYss++ss++++s++++ssst+stst+ssss+tusstss^st+++sst+++stsstssss+++stt++++ss+st++ssst++++s+st++s++++s++sstt++st+s++s+^<u^{VT3 `F5 + T?4HHHH <`$`Z D 8 h  j HtB>22r0hX..H*n !!"#\#$%%& &&'^'(V()* *+:++,,-t-../l0001(123`3456 67P7789"9::;\;<,<<=H=>>>>? ?@@0@^@@ABbBBBCCFCvCCDDEEJExEEFFGRGGGHH>HIIIJ$JJJrJKKLL:L^LLLLM NNBNhNNNNOPPPQQ:Q^RR4RbRRRSS,SZS~SSST$TRTvTTTUUVV>VbVVVWW0WTWWWWX&XLXrXXXYZZZ[[<[j[[[\ \:\b\\\] ]0]]^^8^`^^^_ __``>`f```aab.b\bbbcc,d0eReeeef$fJfxfffgg>glggghh:hiniiijjBjfjjjkkDklkkkllDlrlllmm@mn6oDpppq"qFqlqqr@rxrs s~st^tuuuuv@vvww\wwwwx2xBxRxbxryJyZyjyyyzzzz{x{{|p|} }~ ~<~`~~~~l& :Z@`"Jr"v4DH88 j|JBl| `X`p*:zLlpBf`<bHzD|L^<f tjúDr2Ţhƶ`Ȝ@ɪvʠnˬ,̲B͈VVVVVVVVVVVVVVӈZԈԮՖHֆׄF٢ٴ8hژܢ|DH$|vN 4 > "z&LR\.N,HNvBz"& B   \ v   B$Bdf2@VxDd !@!!"("L"~""""##$$$%%@%r%&<&''2'd'''()))**B*p***++D+v++,Z,,,-.\//0~01123p4@456b6789@9:n:;;<=8=^===> >6>h>>>@@B@@@AADAnAACC,CjCCCDDDDrDDDE"EJE|EGG(GhGGGHHBHhHHHIIBIvIIIK<KdKKL L0L`LLLMM,MRMxMMMNNFNlNNNOODOhOOOPP2PXPPPQ0QRRSVSTRTUUVHVnVWdXXYLYZ[[\j\z]"]^~_B__`azbZccddejfftglh hhhi|j:jkl|m(mmno:opTpqzrrzssttuLuvwx>xyz&zVzp{{&{d{{{||F|l|||}}>}d}}}~ ~@~j~~*bH~6^lp$Jr>dp Nv*\<j FzDf@v(Px|J4\FV(P X ZB:tH`F^HZ.j0><L@|tf²Ú2z&ƘZ ȐVʊj6͐͠ΰ$ϚЎдѸҌҜp*ՠF.bٮښ|ܰݨd߸F  hRb t0&VhzH<P0t6nR"4 R|Rdv .@Rx8 >vV F`r^0h@hH|BT ndfn & T   P  J   F   `B>NNLfZ2h^ $ !"x##$$$$$$$%%%&&&''0'''''(\)2*z+d+,F--../L/0B01,12$23$35 56<6778<889n:v;\;<8<=N=>>?(?r?@@@ABrCBCD&DE0EFFdFGGGHbHIzIJnJKKL8LMhNvOOP6PQR@RSFSTVTUNUVVnVWnWXHXY4YZZ[\L\]J]]]]^^^^_`abd:e:fJg(ghijklklmnVnopqtrHs&stuvvwxpyyz{:{|z}~~RB.HdV<RrH ~BV 6 j"(xP8zjlTT.^F6\d DlF4b:`LNx$\$df <dh @j*X~.V|0f >fBp(`0lF$P~DlBp6l*Pvf*Px.`Bh*Z&ZDj’&ZÎBfČĴ.VŀŰH|ư,RzǠ@pȢ:`Ɉɰ$Jrʢ Hn˖˾8`̺̊R͆ͺ:`΄Ϊ>fόϰ HЀк.fўTҘ$jӰPԊ>xղ(lְ@׈$xز*h٤Zڞ$h۬>܌ܰ 2hݎ"N|ޤXhxTN~6:(Nx N~0v<d@n6T|DrB\Jt$nnX6z*"f8lB4<Z B     v  2     0 @ x N>.f^:F p0XvF>"zBj2`#*011P1~112 2P2~23,5v56"6708Z9D:V;<<=p=>(>?N@2@ABJC"CEEEFGGHHI6IJ`K KL^LMxMN<NO O>OOPVPPQ QBQpQRBRpRS6SST&TnTUUpUVV^VVWFWWX(XxXYYlYYZFZZ[@[[\"\x\]$]f]]^D^^_<_~_``r`a a`aabDbbc.ccddfde e`eef<ffg.gghhVhhiPiij2jjk$krklllllmFmmnFnnoohoppbppq@qqr6r~rssdsttLttu>uuv,vvw wbwwxPxxy8yyz(z|z{{V{{|L||}.}~}~~f~~H@j<d,T|*T~&Pz2vB  >V,$t.bp8z 8Ndz @  ?2/3993310!!7!!IhyJhuC@'     }Y ??+9/_^]]q993310#!4632#"&3ZZVS[\RT\TVXRO[YB@  ?32993310#!#))))-@J   !?O 0 @   ?3?39/]333339/]333339333333333333310!!####5!7#5!333337#/MNLJ/!MMNN/LjjggXD &,{@F'% *!!-.$ **%  tY +sY P?/]]q33+3/_^]33+393339333333310#5&''.546753&'4&'65DωW`Cƥˉ^åMDDn=DɟQ+B6N R@Kng*:,9? "-M@* )#)./ +0+@+ + + &&?3?3??99//3]393333103254#"#"&5!2%#3254#"#"&5!2;-2``2-Y+-2``2-Y}{}J}{}R&1}@B3#'- / $''$ 23#/ $#!*lY!iY?+?+?9/9999939/9/933333333310)'#"$5467.5463267!%3274&#">syKDúߊG4>$~Pe~e:CgH9CM_V\q࿉TV]wYucVf=J,`5=@;Xj0]?9310#))Ry @   $??99331073#&R1 ή27=d @  $??993310#654'3d1:1?V0@     ?9/3933310% '%7)u!㜉'm)hy9w)hpX9 J@.    eJ9/o/]q]]]]33333933310!5!3!!#}}dz?$@@ H/+]]9910%#7!4|A$ =V"@O/]q399105!=u9 @  }Y ?+991074632#"&uZVS[\RT\TVXRO[YD??9910 !D!JJH (@  sY sY?+?+993310!"!2326&#"H5]nl`akm^|so  yN &@   ??9/99933310)?'3NMNMwNP6@ vYvY?+9?+99333310)5>54&#"'>32!Pod,aQUWlhtG}sn;XVNH\L)dteNB&@O"  '(tYE:*" I  $$sY$ sY ?+?+9/_^]^]q]+]q]q+993333310!"'32654&+532654#"'6!2UdoqH[o$O+6hsgVYl0;Ր#q F@#  tY O??9/]33+399933333310#!!5!3!5467#q" %4//i>RNkd5=@sYvY sY?+?+9/+993333102!"'3 54!"'!!76fO^5({7#=O *5 BHP$B@! %& tYtYsY?+?+9/+99933310!2&#"3632#"&2654&#"Hon}GYWd ccjcd^}m` {k{zQw7P'@vY?+9?93103!!%/ HJ".L@'&, ,/0!!)) #uY uY ?+?+93999333333102#"$5467.54$32654&'">54&J|}nxhsrqOaMebNdɿpEXr̻}JOkV`cQCuBbQD<_2.`?EPBJ%B@" #&'  tYsYtY?+?+9/+9933310!"'532>7##"&5432%"32654&JCT\j :r `lbd^}FPV[ë^L|j|{Pwus (@ }Y }Y ?+?+99331074632#"&4632#"&uZVS[\RT\ZVS[]QT\TVXRO[YTVXRQYX?s8@ @ H }Y ?+/+_^]]9310%#74632#"&4|A$/ZVS[]QT\ TVXRQYXX9&@o/]]/993310%5 9TX9:@# G P`WH?_/]3]]]2]9933105!5!X'{X9&@o/]]/993310 5XT=J%J@,  &' ##}Y# ~Y?+?+9/_^]]933105467>54&#"'6324632#"&RmiC`Vmd`3ZVS[\RT\J`PK^:ADb}ƥndGJ<2 88 +2%+%?3?39/3339/]3933333310#"&'##"&543232654.#"!2$7! 4$!2326?&#"\oJs1V QCL@LԞ'psWZY_ .E}ݐG:D?tg610&RB)=9Jb)y%@ iY?+3?9310)!!!sPs^%@  iY?+?3993310# 5!3265^5N!}3 @   ??393310!!!67991 @JM(\"@    ?3?3393310)&'!!>7!>7!H 50 11+%* ,1),63ݢ9B37QNHV 4@    ?3?39993333310) ! ! !V:V;5N5)+"@  ??39932310 !!!1NP\Z/1q 8@ iYiY?+9?+993310)5!!!qVDs"@ $?3?3933310!!#3s B??9910 !!!J3 @ $?3?39333103#5!!3qT/d@ ?2999103# /J}NH/33310!5!NRL!@  _/]9910.'5!?DV?,BeV;u"W@0 ""#$ gYO _    `Y_Y?+?+_^]?9/]_]+999333310!'##"&546?54#"'6323265f;M®evjaK 1QeXZze8@   !  ]Y]Y?+?+??999933102#"'##!36"32654&p31 kpqhkt^opsЏ{E!\s&@  ]Y]Y?+?+9310 !2.#"3267f šZH|>XKJ=-L%/2/$\q<@  !  ]Y]Y?+?+??9999333310"323&5!#'#'26754&#"o 2; hjumo}fqr23}bf쑥!\bs`@6   fYL\   _Y `Y?+?+_^]9/_]]]+_^]99333310"!. 32!3267oanr6/ebP{qq{R*3*.(')uA@  ]Y `Y?+33?+?933333310!!#5754632&#"! ϨϞ{N\NA:yyRR/M1GO^} <@   cY ]Y?+??+_^]_]9333210"'53265!432#"FuTFIMG1pSSVT)kGO7@     ?3??93993333107! !!!Ņ9XD1`TiJ@ ??9310)!1Bs#>@  $%    ]Y?3+3?33?99933310)4&#"!33>323>32!4&#"QWuj)-nY-nQWpoyy^MWNV'yys.@     ]Y?+?3?9993310)4&#"!33>32V^r)3ryy^QS\s (@  ]Y]Y?+?+99331032654&#"!"&5!2m{zkl{zl1̍0s<@  !  ]Y ]Y?+?+??999933310"'#!33632"324&p+kiqhkte;J!R\qs D@# !" ]Y ^Y ?+?+??9/39/9333310%26754&#""3237!!47#otlo{kj< 1ۅ%14PT=kQTws'@  dY  ???+9993102&#"!33>>)%5-4s ^^s\s%:@  &' _Y _Y?+?+999333310#"&'53254.'.54632.#"zKUQ,lZy7ʿ\TLWz:L! (6`$-9&6\wWX$.I)<;5\x/7L>@   @`Y]Y?+?+3399333310%27#"&5#5?3!!wPprX9I#3fA>^.@  ]Y?+??3993310!'##"&5!3265!)1s1V^r1NUsyy^ @   ??393310!!367!V?! '?V^h}qt}^"@ ?3?3399910! #!!36?!3>7!7Vr 0'P # (+^XLU7:Y3 ^ /@      ?3?3999333310 !! ! !ZZ};#d^)@   ]Y ?+?393992310!367!#"'5326?N  G'AOL7AQy"^Rpg[u cd77^ 5@ ^Y^Y?+9?+99310)5!5!!B QT@/  !onK: $?3?39/]]]q39993333333104ᒑ4>3".5}}RcKLbSaRQa>or5CHջ# #IB4rq/@ #??93103#!RR@.  ! onK:$?3?39/]]]q3999333333310#5>5475&54&'523"RcKJdS}}-pr5EF+# #+FD4rpaQRaX'9}N@ @# H?o?_ /]q33/+]39910"56323267#"&'&B7}6gIKb5~6eBxZC6m 7@9m%8u^D@( /_@H   }Y ?+/9/_^]+]q9933103!#"&546323^ZVS[]QT\^1%TVXRQYXI@) sY@sY?]2+?_^]2+9333310%$753.#"3267#3\ӲZH|>ytRd; A$-= RjP@*   xY sYvY?+?+9/3+39933333102&#"!!!!5>=#53546]sNTwgMR@YSۏN,rdq!'X@4"  "() P%o/]3]29933333333331047'76327'#"''7&732654&#"6[ji[55}_esT}6mPQoqONof_57Ynk\}}33{}]hMonNPnpn@?    yYp yYO  ??39/]3+3/_^]3+39333333310 !3#3#!5#535#53!H9<\Zݲ/(@ #??9/9/9333103#3#j,7W@. 2- -&22&895050 mY$mY?+?+9339333333331047&54632.#"#"'53254.'.7654&'y߶Rj{:QJ\y}>?˒QF%ZP}yNl~&4!^TT2"-/.I/EiP(iJO)9u'03"K@d19WE]-K (@ P   /]q3339933104632#"&%4632#"&K@BKLA@KQ}6^ZƬ֭+*/!K@- "#   0y h  ?3]]]29/]39333310'#"&546?4#"'>32%326=1+|Ju}cQBBcD. MYcn:@ujmm u= 2F&$SA$ R^ .@    /3/39933333310 % Rsr=wwwwX9?<@&eJ9/o/]q]]]]33/99310%#!5!9l=VdD&6e@: ' //78p#3+#?3?399//]3]39/3933333331032654&+###!24$32#"$732$54$#"fQYRZdVJ^^m+*լ֭PAIASysb^ZƬ֭+*.@@ H/+]q33310!5! \!@ ?33/39933104>32#"&732654&#"\\^\]]]ɿYBBZ[A@[q\^\\]ZǑ@Z\>?^\X9 F@&     eC9 /3/]]]]3333393333310!5!3!!#5!}}}{/J.@   ?3?3999333310!57>54&#"'632!yf90(Qc{^i`JdY2&(XuUu_;9%Z@4 &'{yh X# !?3?3]9/]]]]q39933333310#"'53254&+532654&#"'>32^h{XNp\SQ23/T9e>g7 nOyFZk5549&2&(/>L!@  _/]9910567!L?V4Ge42^9@   ]Y?+???39993333103265!#'##"&'!!X^~r1+*xX>h 1yyUU.,UJq'@ ?3/39/93310####"&563!>T\P3u)} @ }Y ?   /]+99104632#"&uZVS[]QT\TVXRQYX1@  v/?3]]9/39933210#"'53254'73ND[HNJXr>S=e\JH "@    ?3?9/993310#?'%3H0Nm-Jp_$*=9 '@ 0 ?3]2993310#"&5463232654&#"ᷟ#AHH??HHA\ŧŦdeeddccR^ ,@    /3/39933333310 ' 7' 7ss#;w\\w9;w\\w9.&{'; ?55.&{'t?5Z&u'; -?55=y^'N@-)"()/_ % ~Y%}Y%?+/+9/_^]]q9333103267#"&5467>=#"&54632Ylm9WYO`fbja_5(ZVS[]QT\^JbMNX?9J:*8EliFJ=;VTVXRQYXs&$CR@ %&+5+5s&$vR@ |%&+5+5s&$KVR@ %&+5+5`&$RVR@ %&+5+5V&$jVR@  %#&+55+55 !N@(#   "# iY??39/+299333332310!!!&54632&'4&#"26/jj+qm;%!6**7a*6Y;u\:Xl|$-33-]4%@U   iYF   !  L    I    iY jYiY?+?+3?9/+9/_^]_]+]]_]q_q]q+93333210)!!!!!!!!#%3z\`Nw&&z 7 %+5s&(CR&Ǵ %+5+5s&(v\R@ &k  %+5+5s&(KR@ & %+5+5V&(jR@ !&  %+55+55*s&,CR& %+5+5B.s&,vR@ &  %+5+5As&,K"R@ & %+5+59V&,j"R@ !&  %+55+55/u @W    iY*_oLL>  iY iY ?+?+9/_^]_]q_]_]q]_]_]qq]3+399333333103! )#%4&+3#3 /fe|bңRdT`&1RR@ & %+5+5ws&2CuR&%+5+5ws&2vFR@ &%+5+5ws&2KR@ #&#%+5+5w`&2RR@ &&%+5+5wV&2jR@ +&(%+55+55  ;@!   ?/_/]q9333333310 7   '՘-1-Ӗ-+ј-՘w"L@+  #$! iY !iY?+?+999333310!"''7&!27&#"4'3 ŋZZiQƒTX8Ti3 LhszAlmF}ht-u'^s&8C+R& %+5+5^s&8vR@ &t %+5+5^s&8KR@  & %+5+5^V&8jR@ (&% %+55+55s&<vR@ &n %+5+5 <@  iY  kY??9/+9/+99333310!#!!3232654&+6 Dd|54&#"!4$!2*@J@*5Bi3c<5@ RJ~bFFM>dt%&@aL:0*4([bzN"$2{)3<*HwQ@j17P.32!3273265"!.1HbŞYMcsBx-ĸOAq||ex#jeiuY TEBMe@A锂X'(W[zep|\s&Fz %%+5\b!&HC $ %+5\b!&Hvs ! %+5\b!&HK ") %+5\b&Hj !. %+55!&CO %+5!&vE y %+5!&K  %+5&j %+55\'w@A " ()]YaY_Y%_Y?+?339/+9/9+9/+9/93333310&'77#"54327&''4&#"326Y?endF@dzkyoxp{j;"CKhbzll&QR3% %+5\!&RC" %+5\!&Rv y %+5\!&RK  ' %+5\&RR * %+5\&Rj , %+55X9|@$   P `   @1 H /OoeJ9/o/]q]]]]33/]32/+]qr39333105!4632#"&4632#"&XJBBIJAAKJBCHJAAKdLKNIFRNKMQGFQN\#M@,  $%! ]Y !]Y?+?+999333310!"''7&!27&#"4'326~lCDt7:=+?zl &6zk1-eid04RlT^HQ<2!&XCx %+5!&Xv t %+5!&XK1 " %+5&Xj/' %+55!&\v= c %+5!A@" "#  ]Y ]Y ?+?+??999933310>32#"'#!!"324&2ih1qhkteQỦ>^;yxHN!R&\j ) %+55&$MXR@ %&+5+5V;&DM &%%+5}&$NVR@ %&+5+5V;+&DN )#%+5&$Q{!%+5VLu&DQ12%+5ws&&v R@ & %+5+5\!&FvV %+5ws&&KR@ $&r$ %+5+5\!&FK ?#%+5wf&&OR@ &n %+5+5\&FO; W%+5ws&&LR@ &t  %+5+5\!&FL P%+5us&'LhR&%+5+5\%&G8o \(( %+5/u\ 'k@:%%   )(  eY"]Y  ]Y?+??9/_^]+9/3+399933333310"5323&=!5!5!3##'#'26754&#"l ;2; hjunq{fqr$!e3ǡT}&(MR@ & %+5+5\b&HM   %+5}&(NR&  %+5+5\b+&HN  " %+5I&(O/5@ &  %+5+5\b&HO?  %+5&(Q5 %+5\(bs&HQ? '! %+5s&(LR@ &  %+5+5\b!&HL % %+5w's&*KR@ (&U!(%+5+5\q!&JK  -4&%+5w'}&*NR@ &[!%+5+5\q+&JN -'&%+5w'f&*OR@ "&f%+5+5\q&JOP "'+&%+5w;'&*9 R# %+5\q!&J: ,/&%+5fs&+KR& %+5+5&KK5#&# %+5+5@X    qY   iYF!L;  ?3?39/]]]]]_]q_q]q+_^]9/_]33+33993333333323103#!!!#535!!5!5!fʸ6C5w-ô_@3     eY ]Y   ?3?9/]+9/3+399333333310)4#"!#535!!!3632ϴsϜ1;fP/ǡS.`&,R"R@ & %+5+5&R %+5?&,M$R@ & %+5+5&M %+5}&,N$R@ &  %+5+5+&N  %+5B&,Q  %+5^&LQT 3 %+5Bf&,OTR&  %+5+5^@ ??9310)!1^BR &,-ߴ %+5)&LMJ %%+55hR s&-KR@  %&+5+5}!&7K %+5;P&.9%+5;&N9u %+5^<@      ?3?3939933333107! !!!ύ:EHƏ1FnZ^ۡR?s&/vR@ %&+5+5&Ovg@  % &+5+5;?&/9Jٴ %+5c;&O9%+5?&/8u # %+5?5&O8 %+5?&/O/p@0@pR %+]5&OO8 z%+5? @@!     @ iY?+?9/99933333103'7!7!Eq6uQ)oXĞX 3@     ??9/9933323107!'7!FtHq1+ph+p-s&1vDR@ &p%+5+5!&Qv r %+5;&19´%+5;s&Q9u۴ %+5s&1LR@ &%+5+5!&QLN  %+5'Q %+5R;@  kY"?+??399333310"'53267#!!35!rS]Irj {RYeN}P{wJs:@ ]Y]Y?+?+??99933310"'53254#"!33>32=kM;<{r)2tʼ۫^OUw&2MR@ &%+5+5\&RM  %+5w}&2NR@ &%+5+5\+&RN   %+5ws&2SBR@ (&m%%+55+55\!&RS{ [) %+55wP#@U  $%iYF!L I  iY iY  iY iY?+?+?+?+9/_^]_]+]]_]q_q]q+9333310)# !2!!!!!"3267.P&-S>=#d3Az&# ik \{s+2@I &00&34 /fY/i/ //// ,_Y )]Y `Y#]Y?3++?+?+9/_^]]]+_^]999333333310 '#"&5!2632!326732654&#"%"!.pGkdQfm{zkl{zl^| u-OM*.'(Esyo}Hs&5vR@ L %&+5+5!&Uv g %+5;H&59 %+5c;ws&U9 %+5Hs&5L3R@  %&+5+5S!&UL %+5^s&6vNR@ {(,%0&+5+5\!&Vv r'+%+5^s&6KR@ -5%5&+5+5\!&VK  ,3%+5^&6zb.(%+5\s&Vz-,&%+5^s&6LR@ 0(%-&+5+5\!&VL .'%+5);y&79)  %+5/;7L&W9%+5)ys&7LR@  & %+5+5/(&W8@@ Hz%+5+5)yE@#  iY  iY?+3?9/3+393333310)#53!!!3#sPsTb/7L\@.      eY `Y]Y?+?+333/9/3+3993333333310%27#"&=#535#5?3!!!!wPp4IX9I#fƔA>^`&8RR@ &# %+5+5&XR1 % %+5^&8MR@ & %+5+5&XM/ %+5^}&8NR@ & %+5+5+&XN1  %+5^&8PR@& %+55+]55&XPN %+55^s&8SR@ %&q" %+55+55!&XS x$ %+55^&8QH  %+5^&XQ#$%+5s&:KqR@ +&$+ %+5+5!&ZK ")%+5s&<KR@ &%+5+5!&\K $ %+5V&<jR@ & %+55+551qs&=vNR@ &i  %+5+57!&]v   %+51qf&=OR&  %+5+57&]O  %+51qs&=LR@   %&+5+57!&]L  %+5? !@  ]Y?+?93310"!4632&Pϼ͞xG\-\//L@&    `Y]Y]Y?+?+9/+339933333310#"'5325#5754632&#"3#鼰kM;;}–pHR?myqRR/F!-p@D/ ( "" ./@H@ HiY?o %*?3/]29/]q+++9/9333332310!!!&54632 &'5>7!4&#"3>/jl+pm1fVDpL.jVl6**7V&2U>J#:Wn-!EG*x t7-33-\3V; ",8D@U'?3-9",,93EF/<6 6B0@ H0 #gYO_  `Y)_Y?+?+_^]?9/]_]+9+2_^]2]]9333333105>7!'##"&546?54#"'6323265#"&546324&#"326.jV;M®evjeppqn6**710*6*x iD'aK 1QeXZzelnli-33--44%s&vRw@ %&+5+5V!&v _9>%+5ws&v1R@ +&n$( %+5+5\!&v{ m%) %+5^;&69+,%+5\;s&V9δ.+%+5! @ _/]399910&'#567!TMN˽CeH]SQ_p4F!@  _/]299910!.'5367Tlw˓RT!T2/{]SWY@G_/]3]9910!!Z+ *@ F V f  _/]33]/]39910#"&'3327 ܦ/UU+/6} /39310432#"SSGOTJ &@   _/]32993310#"&546324&#"326Jppqn6**600*6lnli-33--44 @  /?3933310327#"&54673-#73232673#".9 v)OMJ$9 t)OMJB56!' 46!'!! !@   _/]229105>7!3567!>o- J8-lU)56m+QD^@  _/]9910>7!#5 Nm6T 8@  ! P   /]q3339/9333104632#"&%432#"&'>7!#G:9JJ9:G#9JJ9  iY iY?+?+9/_^]_]q_]_]]q]++93310!5! ! 32654&#"3iQQeϿfzmm|B,P.3 @   ??393310!!!. 3 R <>)Jo01R? i@C   iYF!L I  iY iY ?+?+9/_^]_]+]]_]q_q]q+910!!!!!Rdw=Hw2=%@ iY?+?3993310)!!!=L3NyE@"   iY iY?+3?+399993333331035 5!!"' 63!N5J3#-  = )y7<\"+R@*'""+  ,- * *kY$$kY   ??99//+99+99933333331032654&+5#"$546$;5!32+#";)衏55)9V;m@@   kY ??339/+3393333310!#!# !;!3265!33"#L !7 F@$   !" iY  iY?3+3?+33933333310"!!&54$3 !!654&%Ąs<?yv}H]AƸ`H9V&,j"R@ !&  %+55+55V&<jR@ & %+55+55\^&~T1 430%+5N%^&T% [/,%+5^&Tw ` %+5^&T  %+5&UD'%+555\q *D@$" +,) ]Y%aY ]Y% ?3++?+?999333310%26754&#""323673327#"&'#ovko{kv2+ 'T [pv"nߏ 00TT^7ahv MZ)d@7"' '"*+"##"]Yi#"# # ## ^Y ]Y ?+?+?9/_^]]]+99333333102#"'!4$"32654&+532654&~0<|H5cnnй?4'|pnsmf\d^"@ ??3939310!47!3>7!8,V=B9=c-6VR>I,Yt\)C@"$*+!!' `Y']Y?+?+99393333310&54632.#"!"$5464&'326oэy\XIJC_i{xioz-B-76.6iF^Ҷ]:#~e}N%s&w@G# '(&&{Yk&Y&&&t&b&&<&& & &&  `Y ^Y ?+?+9/_^]_]]]q]qq+993333310#"!267! $54675&54632.#"3H gY瀐sX^wMqnAH}-)Mk 1э.&026B7\ 6@  !" _Y?+3/.39933333310!>54&'$4%#!5!EOOfH43V'IgA%]/ )M~ ߶JZ5 !}s/@     ]Y?+???9993310!4&#"!33>32V^r)3ryyy^QS\ n@B`YL~m$I*/  _Y  _Y?+?+9/_^]q_]+]]_]q_]+99333310! ! 267!"!. uk7iyln inxl>y^ @   ]Y ?+?99310327#"&5I#3^!"0@#$  aY aY?+?+?939103'.#"5632327#"&'&'##$\_24OWss3%L7!$r'n)r+ .!\ZJ Fhb lwC4L^ws^ @   ??299910!36! !9Esf4X^+\.^@0& # #))/0 ,bY / & _Y ?+3/9/_^]+9.39333333333104675&5467+5!#";#"!>54&'.\ۇC$K끓/aEOOf~6 4k% ҉u_R{{GU5!}f]/ )&FsR^=@    ^Y^Y?+?+33?993333310%27#"&5!!#57!#C?)66#Buf31ys-@   ]Y]Y?+?+?993310#"'#!32%"32654&ښqj+t#3f^)@    ]Y?+?39933310 !32654&'!2ir}r+3( `kַv\u #E@# ##  $% _Y `Y" /3+3?+??9333333104&#">$5474632^Z9@nxZJֺNOa a zy4 m F@#"!"aY aY?+?+??9999993332102!327#"&'!.#"56ZrP)J39F=14Un}4hF88;rm3q{%@5 Fu`F>FA@!  ^Y ?3+3??3?933333310>54!!$!PN#<& !3ŭ ;m{^'C@!! % () ! ^Y?3+3?39/993333310"&'##"47!3265!3265!z) .w0@%}c`SLLT^d}%@1iind.Ѥt'هs3 &j + %+55&j'(%+55F^&RTB k" %+5^&TN 6%+5m{^&T5 N0- %%+5V&(jR@ !&  %+55+55)H@&   iYiYkY?+?+3?9/+93333310"'32>=4&#!!!!!!2mtWcI62S_ZJ\&+D7YG^νTs&avR@ &k %+5+5w#r@I iYI*]L!Hn I iY iY?+?+9/_^]q_]+]+]]qq++93310"!!327# 4$32'&J y ɼjzMloWɿM(#jW70%<^6B,9V&,j"R@ !&  %+55+55hR-#m@A$%#iY0]s  iYiYiY?+?+?+9/_^]]_]_]_]q+9333103 )! #"'5326!32654&+s'i>_T@:35>7[ X^HeaW Hefc[@S  iY   iYF   !   L ;      iY?+??39/_^]_]]]]_]q_q]q+_^]+933333310)!!!!!3 32654&+i#65s'X^Hw=aefeY)>@  iY  iY ?+3?39/+9333310!4&#!!!!!!2FPZJYG^Ѻ`s&vR@ &X %+5+5N&6sR@ &%+5+5V= 0@  "iY?3+??3933310)!!!!!=TR65VL$ e@;  iY0]s  iY iY?+?+9/_^]]_]_]_]q+993333103 )!!32654&+z8VhO7HefeY%Ta V ?@     "iY iY ?+33?+?393333103!3!!!! q)Tl ];"COLTV^(@@"     ?33?339933333310 !!! !!!?!@<<B^&z@I!  '(kY1EV$ I*  $$kY$ kY ?+?+9/_^]_]+]]qq_q+993333310! '3 54&+532654&#"'6$32ȫ^nq{ԅ}`O-3ahXfKYwSM(@    ?3?2999933310!3!!4#! sZ>VJ&6R&%+5+5` 0@   ?3?3999333310)!!!`6 J<B=)@ iY iY?+?+?99310)! #"'5326!=>_T@:35>7[ eaW 0f+w2=n3w&)y7N)@   iY?+?3939310 #"'3267!367N;U˓~lZQf$Hi 5«S $Jb8{|\sV;V 2@   "iY?+3??3933310%3!!!!!=65`Lm+@ iY ??39/+9933310)#"&5!3267!ʚ]5buRw654&ɶ\jk!) 1@   iY?+3?33933310!!!!!!568JLV;@   " iY ?+33??339333310!!3!!!!!5"68@`Lu c@:  iY0   ]   s   iY iY?+?+9/_^]]_]_]_]q+99333210)!!3 32654&+uV{8/hPaefeY c@; iY0]s  iY?+??39/_^]]_]_]_]q+9333310)!3 32654&+!!p6d5NQC5beffXy X@4 iY0]s  iY?+?9/_^]]_]_]_]q+9933310)!3 32654&+V6z80hO7aefeYHs@I iYI*]L!Hn I  iY iY ?+?+9/_^]q_]+]+]]qq++933310"'63 !"'3 !5!.)c]bEcx8'gq}KMt@P       iYF   !   L ;      iYiY?+?+??9/_^]_]]]]_]q_q]q+_^]93333310! !!!!! 3 4&#"6"I<N+LwM>!3x G@%   iY  iY ?+?39/_^]+3993333210 !.54$)!#";| ʙx12юJ1VdapV;uD\$G@% ""%&_Y aY]Y?+?+9/_^]+99333310%>73>32! 2#"\%7my#~Q,5d16kY5$+PmRXox+#2Q)^ x@F  !"{Y9(M<   bY  bY ?+?+9/_^]_]]]q]q]+9933333310#!!24&+3264#!326qnw=ffaead9Zc^B;If8^@`Y?+?99310!!-^^o1^B@!   @`Y _Y ?+33?+29333310%#!!!36!3\WMw^`op$\bsH^;@      ?33?33993332310!! !!! !;dVVd;?77FN#s(w@G# ##')*'(('{Yk(Y(((t(b((<(( ( (( `Y  ^Y?+?+9/_^]_]]]q]qq+9933333102654&#"'>32# '532654&+5jzMPZw߉uV`v8=66&!-'9 "}efVE(.C>DA#^ (@       ?3?39993310!!47!o^FFw^#?&6  %+5^ .@  ?3?39933310! !!!}PE71^7^^)@ `Y aY?+?+?93210)! #"'5326! \|jD119M=Ny O!^*@    ?3?339993310)#&/!!>!!6++13 !%,q>l nD^#MGn^ N@/   `Y$ Hv$ I   ?3?39/]+]q]++99333310!!!!!1V^R3^\sR^%@ `Y?+?3993310!!!k^y^sS\sF/=^%@ `Y?+3?9310!!!5=^y^\\'L@'   !`Y `Y ?3+3?3+3??9333333310!$54%!4&'>>4&ŚXd/%d ^[od^ 3@    `Y?+3?3933310%3!!!!!N12^y{^+@   _Y  ??39/+99333103267!!#"&5XM1jU^g( 8.!^ 1@  `Y?+3?33933310)!!!!!!1w1w1^yyo^<@    `Y?+33?339333310%3!!!!!!!!1w1w1^yyf^ ^@8   bY$ Hf$ I  `Y bY?+?+9/_^]+_]]++993332103 )!54&+325gh^PyA:-^ ^@9  bY$ Hf$ I  bY?+??39/_^]+_]]++93333103 #!!4&+32!!ѓ11Xhg1^A:^^ S@2  bY$ Hf$ I bY?+?9/_^]+_]]++99333103 )!4&+321hg^A:Jsg@@  fY   ""#H "H9  M <     `Y`Y?+?+9/_^]_]]]q++q+933310"'532!5!&#"'>3 ҆ZwVK^EP?#-sh@?     `Y $ H f  $ I    ]Y]Y?+?+??9/_^]+_]]++93333310#"$'#!!36$3232654&#"1%bqobcpob13^R^ G@%     bY@ bY?+?39/_^]+3993333210).5463!!#;#"J-loϨnYKU-sbFOI\b&Hj . %+55&o@<$'( eY  ]Y    ]Y?+??9/_^]+9/3+3993333333310"'53254&#"!#535!!!3632=kM;<{^VsϜ1;fʼnn/ǡS!&v g %+5\sf@@fY""#H"H9M<   `Y`Y?+?+9/_^]_]]]q++q+93310 !2&#"!!3267!Xkis[ngOf#* JAz}˃}$,I\sVL&j %+55}M^h@> !bY$ Hf$ I `YbY aY?+?+?+9/_^]+_]]++99333210!# #"'5326!32!4&+32- \|jD119M=#bay OP`A:^o@B  bY `Y$ Hf$ I   bY?+??39/_^]+_]]+++93333331032)!!!!!4&+32^;1\1Dba3^RA:_@3     eY ]Y   ?3?9/]+9/3+399333333310)4#"!#535!!!3632ϴsϜ1;fP/ǡS!&v P %+5?&\6  %+5o^ 1@   `Y?2+?39333103!!!!!12x^yo}'@ iY?+?993310)!!! q6/@  `Y?+?_^]993310)!!!^1s&:CR&&"& %+5+5!&ZC $%+5s&:vR@ &&H# %+5+5!&Zvd d!%+5V&:joR3&0 %+55+55&Zj .%+55s&<C|R&j %+5+5!&\CY %+5R@ O/]399105!R\R@ O/]399105!R\R/399105!R\1N4@  H H/+3+]2323310!5!5!5!NRR1@  ?]9910'673'e5B#[q@ ?]9910#72~E(?$@@ H/+]]9910%#7!4|A$ @  ?]9910#&'7?%@;a Uw"@  ?3]2910673!%673!e5B#e5B#[q[qw "@   ?3]2910#7!#7!2~E2~E((? /@   @ H/+]33/]3910%#7!#7!4|A$4|A$  { >@    ??9/333993333333310%!5!%77777LB_qi@9      @   ??99//]]3339/3339333333333310%%!5'75!%%dL87K//K78L/-yxb) @    /]99104632#"&b욣ub9 #&@ $% }Y! ?33+3391074632#"&%4632#"&%4632#"&uZVS[\RT\GZWS[\RU\HZVS[\RT\TVXRO[YQTVXRO[YQTVXRO[Y?  "-7Bc@6.>83 )#) 3>CD +0@1;;;@5@&?333?3??99//3]333933333310 #3254#"#"&5!23254#"#"&5!23254#"#"&5!2+-2``2-YP,2``2,X;-2``2-YJ}{}}{}j}{} BR^@ //933310 Rs=wwR^@ //933310 ' 7s#;w\\w9u'H-!%+55w??3310 #+Jf H@0     P   0 @ p  ?3?]qr299333104&#"#3363 D<9ZHǢIL@`qTe/#'Y@0  yY wY  wY ?+?9/+9/_^]3+393333310!!!#53!!!!<ϕoRj%w@B  " &' ! yY !!!! !yYsYvY?+3?+9/3+3_^]2+39333333333102.#"!!!!!!5>7#535#53546]NEPLggFJdKR#VVqsJl'*jUss)z@B #''%*+"" #&#&xY## wYP     wYxY?+?+?9/_^]]+9/+333/933333331032654&+!#!! 27#"&5#5?3!!B~T5uNSaXHhumh#3>lgGD==DG>Zud7f@IItZOJĨǤdeeddcc82)f_+-)$H@! "  %& "    /3/399//3/999933333310%2673#"&=56746324#">32!3267.#"y1RQHbٓ2Xz#5Fi)|5Bu:''>{ ?555;''>u ?555Z''>< ?555C''>= ?555;b#I@)"" $% `Y   ]Y]Y?+?+9/_^]+933310#"&54632&#"63227.#"bܼӕiT6Vg N5FsI@Ϯ6)69Z644lp9 -@     iY?+?9999933107!!!'&9^/i(Z $ W4'7H%@ "iY?+?3993310!!! 7})7 @@"    iY iY"?+?+9999933105 5!! !)? H7Bo Xd9?4@"eJ9/o/]q]]]]399105!Xd%<@& @ H/+]q/99//39310##5!3Elq{7#)[@6" "'' *+"$ ?_/]q3333/333993333310#"'#"&5463263227.#""32654&7{;Os}XN&P28EEjWQPZ8DF͎İM]DCM<JXP )@  ?/9999333310 # 3 P=r=r!fg)&IL $%+55)&IOO%+5h3? @  _/]33/39910#"&'!32673Ysec ?gS[_}^ @  ]Y?+?93210"'53265!FuTFIMG1VT)^ ?9910>7!#^'PV1@^; /9910>7!#^'K[V1@N!@  _/]9910!5673'NX1@ J B@"  X  ?3?9/]33]39933333310##5!533!547}} 5ᗗAͤVblT9:@ p !?3?39/]3993333102#"'53254&#"'!!6d27WQ?8m%84 *?@+;J @ ?39?9310!5!TMJ)-5!-D@&%+ +./e(u(((  " !?3?29]9333333102#"&5467&54632654'">54&CLKB#GW:9;F=E2&1%  -, 48!59/33/33399/]]q3_]]/3/33/33/39/_qq3993333333333333333333333310!#%5!#533!5353!5!!5!5!#3#35!#35!35!#35#3#3#"&546323254#"%32+32654&+32654#"'53253T/0momImmmm0oowoooomm~smp.,;0m^{B.$*/;J1%Z^4+V}i0oo/mmmmmmoo;mmJoooo/yhIaCS1D D8QYb" "+%J fVr_cT*,@ % +,((""//99//339910 5467>54&#"63232654&#"TV,AgIOGRZ?>1HT;GFBIHCHEVW/2A1R~X8*P:/5K6DpJ;?HI>@IH}!&7L  %+5)3s@C ,311&(,452(/332`Y33 /^Y0Pp  //`Y/ #^Y ?+?+9/_^]+9/+999333310.#"! 4654&#"'632326='&$&5463 3cJ *0LZga\ơWߦlp|+-K5i+*V^X?GKO!t͊(@ kY?+??9993210>32&#"!!}>xhu_UB,(5C6PTB +'`/3^(X@-  #  )* !!  `Y &^Y?3+3?+339/99333333310"'##"547!57!!4'!326=!326FS R??3@>\gTLLTg\fѲɰssu&0vT@ &j %+5+5B!&Pv i%) %+5&$Xs %+55V;u&DX  )#%+55xG @XN 6@   O    /  @H /+]r3/q3993310#"&546324&#"326Nppqn6**600*6lnli-33--44X,(@ ^Y ]Y)]Y?+?+9/9+10.#"3>32#"&54>3&#"3265v?9%h2?JPNA5!# 5!3265^JF- k5jg¢!isP@+  P   ]Y?+??39/39/_^]q9333310!'##"&5!3265!>5!)0s1V^r1GN- lMVsyyutfW!C!vR@ _/]]29/310#'>54&#"5>32 K6*"AJi)Ϝ)G 3% " oR%}  /]310432#"٦TR疖GNs&(CzR& %+5+5s&CTR&v%+5+5\b!&HC $ %+5#!&C  %+5w=2P@(+(#+( 00(34))  kY-&&jY ?3+3?3+39/993333310"'>3 !"&'# !2.#"327!3254&'ZDl@K )tMMt) JBlD[&SU6Hl!-175!!.'!!):9{)TCGV({ų$Ջ+%;|dqe{{9^g@  eYe@ H o bY?+?339/_^]q33+]+393333103>75!!.'!7!u(}[4Yy*t^8/6<^hZ} mjj {'MB ? DNm"@i!"    #$ lY 0   iYF   !   L ;       "iY ?+?3?9/_^]_]]]]_]q_q]q3+_^]/_]q+33933333333310!67!!!!5!!.'!!P,36C9{)TCGV({3+%;|dqe{{9^"@!"    #$  @C H eY `Y $ H f  $ I     "bY ?+?3?9/_^]+_]]+3+/_^]+33+_^]933333333310!67!!!!5!!.'!7!#u 3Yz)u^54&+532654&#"'>7&'53>J0>]_\b)YhZ6ì{ԅϾSw`6NWe "')X)enahXfKYw6Lw(dN./#dH@V >6 "##G ,> &CC >IJ)A^Y)"GHHG{Y)HH HH HHI 32&#"!"327632.#"# 463 54&+5jzMPZ{]W9RVc;H3"6TJ~сolaKYUON0V4D|v8=66&!0l_)fL- o"a9 "}e'44*)3DAmuFw t@IiY*FVL!H I  iY  iY?+?+9/_^]q_]q++]]qq+99333310! ! 267! !.iQQeH7zmm|\s k@A{Y""#H"H9I]L   ]Y ]Y?+?+_^]9/_]_]]]q+++99333310!"&5!227!"!.>ndm1̍0ttpq @iY ?3?+?9210"!!67>32&B.@*9!+67\xVtF3GvsK'f @ ]Y ?3?+?9210!367>32&#"!?2 ,{3LkULH+' 3^Oo|Xj1,7s&}s'R)&$%+55+55!&~s% %+55w  .I@'!0 .'/0..%  iY iY%*]Y%#?+?+?+?393933310! ! 326&#"%!367!#"'5326?LECK JN  G'ANM7AQy"{xxvRpg[u cd7\ )s&R\ # 2%+5w91(X@, #'!! )*0jY %'0#' 'jY ?+99/+9993333310#"'$%>32>32$%#"'9#qv.$D=5H1}E0-E'ff)(ss$FC{&<2,B&%**JMKKM\+V@,$* !! ,-'*0$**^Y0 `Y0 ?3+3?3+393333310#"&'&547632>32>54&'#"&' H69G nj99+>SOPI>=6D1&5:;6'%#!RR">'+!3~/816Aw=1GY{@H#TKHO //3OK=Z[I9Y9i9WpWWW KWKW9233===9B  kY,&&jY ?3+3?3+3/33/_^]3399//^]]9333310"'>3 !"&'# !2.#"32673254&#"'.#"#54>3235>54.54632'ZDXcGRKNxRw>/-!pcenA6) 3;1bt6&-&]V:5:Z\R)@R@VMDAH#+HD5STDDPP`PpPPDPDP1*++55`5p5515;;; ;  `Y `Y&?2+3?3+3/_^]33/]]3399//]]q9333310 32.#"3273265#"'632!"'#"'.#"#54>3235>54.54632f|V?B%wlmv'A>V||z&g2.+ ":fT:pwN2B%,%NGNT)&< V$&-&^V ;4:Yw=B&i h >&@4 %+5+5&j h '%+5w#1@ # iYiY?+?+?9933310 4$32.#"!267!ZMe[Z:NjWg':\s1@ ]Y]Y?+?+?9933310&!2&#"327!Z!Xh~rw}* PB% hy ;@      ?99333333310%'%7%7%LG㴁FGJ{J;{Z}9IĤ{{<@   @ H  )  //]33]2+993310#"&543!632#6083m bm69+3G8u^s9H 2@  ` p  /o/]33/]3/399102>32#.#"+5Nwp:in? +.IJ%-&6ua1;47X@ _/]93104632.TNGN%-%D1IY:5 : VX"@ _/]9933105>54.546320E%-%NGNTbV ; 5:Y) (6DR_m@iP4H, B&:V^&,c4k no-&44)"00)d^Wkk`ZggS`IB;PPE>LL7E)`EE`)P     ?o/]2q2/]]3q29///333q2333q2333q29333333102#.#"#62#.#"#>2#.#"#>!2#.#"#>2#.#"#>!2#.#"#>2#.#"#6!2#.#"#>]qO?#&*-O;_;;;;6@3P3333.6-&..&-6  ?/9////////]]93310#67'>737&'.'5467'67".'7&'7 F$a5; Ia4#GA݁hBO݁E?軋Ek(8PC{Lh&ZC7#BO݁GA܂ Ia5; F$a5[8D.^3DuOW.FcB=FKV+!K@'   "#! " jY ?+???322/39993333310!3!!!!4#!#"&'!3267 sNZwYsce >VTLgS[_oN? G@%   !"  _Y ?+??322/3999333310!!!!47!#".'!3267o+މ)g  Yqgd^FFw^ὩJlN_[/@6       iYiY0]@ Is   iY ?+?9/_^]+_]_]_]q+9/3+_^]399333333310!!3 )#535!32654&++z8V6hO7!HefeY@U eYbYQaf$ I bY?+?9/_^]+_]]_q_]]qrr+9/+999933333331035!!!3 )#4&+321ymhg5?oA:`@4   iYP      iY ?+?9/_^]]+9999933333310'+!! 37'7654&+_]XsVr DLe)w>}p5mn5Zmhs(S@- !&&$!")*#$ ]Y`Y?+?+??99993333310"'#!33>32'";7'7654&p+6c^l4qhktje;JSSѠ{v!{Nl/P =@   iY  iY ?+?9/3+39333310!!!!#53PoʉTd^ =@   ^Y  ]Y ?+?9/3+39333310!!!!#53Lω^^yZ@5  jYP `    jY#iY?+??+9/_^]]+993333310"!!!632#"&'32654&m5Jk1nJ o ס/Ͱ ^J@'   aY ]Y aY?+?+?9/_^]+993333310%#"'3265!"!!!632zr-y1t}*.1JKD31^ VL@*    " jY?+??3?339933333310 !!! !!#!!?!@R=ը<<BLoX^P@+      _Y ?+?3?3399333333210!! !!#!! !;d VVd;?77F^&|ٴ5/!%+5N#s&|1δ71%+5V=@    "jY?+???399333310!!#!!!Gո6 J L<Bo5^B@!      _Y?+??39993333310! 3!#!!}PE)71^7^PP@(     ?3?39399999333333310!!?3! !#j|6zXdZcbGy^H@%     ?3?29999933333310!737! !#'!c@        `Y?+?3?939332310!! !!!;F7^7yV@M      iYF   !   L ;       "jY?+???39/_^]_]]]]_]q_q]q+_^]93333310!!!!!!!!f+6C5 Lw=o^f@<     `Y$ Hf$ I   _Y ?+??39/_^]+_]]++93333310!!!!!!!1V^R3^ |@J     iYF   !   L ;       iY ?+?3?9/_^]_]]]]_]q_q]q+_^]993333310!!!!!!!6C{Lw=^ `@9   `Y$ Hf$ I    `Y?+?3?9/_^]+_]]++993333310!!!!!!V^R3^ `@9 !"jYP`  jY #iY?+?3?+9/_^]]+93333310632#"&'32654&#"!!!!s"mP:b\#ס/ըL ^R@-  aY `Y aY?+?+?39/_^]+93333310%#"'32654&+!!!!72yr-y1sPD3y^w)4x@'//$2**2!$562,',lY'' '''@ H'' kY kY iYiY?+?+/++9/+_^]+9933333310327#"'# !2&# 327.546324#">bq.BLD>thE>8.N\Nȱ?Mǿp7>8&=Jpb"W}L}{jz18\s*3{@%00%2++2"%452. (._Y(( ((@ H(( _Y    ]Y ]Y?+?+/_^]+9/+_^]+9933333310327#"'#"32&#"327.546324&#"6VN*;@HTb*y0CX8ohol *,-ZLgv4V"74OM9H~W@w&&|9 j% %+5\s&F| Y$%+5)Vy 7@  " iYjY?+?+3?933310!!!!!!+sPs L/o=^ 8@   `Y _Y?+?+3933310!!!!!5=^fy<^&@  ??3/39932310!!367!NP $"NM^I<`F@#    iY  ??399/3+39993332310 !!!!!!5!1N??P\Z)^@@  `Y?3+3??399333332310!!!!5!!367!#NP $"NM^I<`VF@$      "jY?+???399993333310!!# ! ! !%ժ:V;5N5 L)+ o^F@$     " _Y ?+??3?99993333310 !!!!# !ZZ;#d)VHB@"  "iY  iY?+3?3+3?9333310!!!!!!!!;i6+NTL/o7^D@"    `Y `Y ?+3?3+393333310!!!!!!#51^lyymVFE@&   iY    "jY?+??39/_^]+9333310!!!#"&5!3267!+ʚ]5buRw6 L54&ɶ\jk!){o^>@   _Y _Y?+?39/+93333103267!!!!#"&5XM1jU^g( 8.mN@)    iY??39/]+9939933333310#"&5!367!!#q((5bmY6ʁnɶ\neH 3J5-{^H@$    _Y??39/+9939933333310#"&5!;367!!#F31}N^1iC}Zg)6f-@  iY ?3?9/+9933310!>32!4&#"!6[buOv3'Ǹjk *q^-@  _Y ?3?9/+9933310!4#"!!>321jWH^D8.`!(s@@% & &)*  iY%X "iYiY?+?+9/_^]_]]]]3+33/99333332310%2$7# #"&5473;! !"!4&bLn}?5`)%d%\[ ҕ ]DKBU6ztYHX8u|Gݳ`s%k@;##&' fY"i _Y `Y?+?+9/_^]]]3+_^]33/933323106$32!3267# ' 54733%"!.N!jbN)`%^| w+-'(`E75Nsyp|V$+~@G (#$))$,- iY(X $"%iY"iY"?3+?+?9/_^]_]]]]3+33/93333332310&#"&5473;! !32$7!"!4&?5`)%d%\[ ҼLnm~ (IztYHX8u|G]D@> duo`s 'v@A   %% ()   fY$ i    !_Y_Y?+3?+9/_^]]]3+_^]3/3/933332310.' 5473;6$32!3267!"!.ݵ)`!jb^| w(`E75N+-? +syp|B,&6uR& %+5+5?&6/ %+5F@#   ! lY jY ??3?+9/+39933333310"!!7!32#"&'32654&Ko6X/nJ@Pס/Ͱ ^F@#   ]Y aY?+??39/+39933333310%#"'32654&#"!!!2yr-y1t~2z1X'D3 ^ V;@"jYiY iY ?+?+?+?933310!!!! #"'5326!=N>_T@:35>7[  LcaW o^:@ _Y`Y aY ?+?+/?+99333210%!!!! #"'5326!+݉ \|jD119M=Ny Ofz@I   iYF!L;  jY??3?+9/_^]_]]]]_]q_q]q+_^]993333310%#"'3265!!!!!fKR~6C5Z/= ^\@7 `Y$ Hf$ I  aY ?+??39/_^]+_]]++993333310!!!!#"&'326711Lv@prlo3^R :V@O      iYF   !   L ;       "jY?+???39/_^]_]]]]_]q_q]q+_^]933333310!!!!!!!!fN6C5 Lw=o^j@>      `Y$ Hf$ I   _Y ?+??39/_^]+_]]++933333310!!!!!!!1+݉V^R3^mVE@&   iY    "jY?+??39/_^]+9333310)!3#"&5!3267!]5buRw6V+4&ɶ\jk!){o^P@-   @_Y/o   _Y ?+?39/_^]+93333103267!!!35#"&5XM1jU^g( op8.V!I@'   " jY?+??3?39933333310!#!!3!!!!46## ZoN {uX^TL1oL^@@! _Y?+?3?399333310%!!!#&/!!>!!+މ6++13 !%,q>l nD^#MGnB,&$6uR@ %&+5+5V\?&D6) .)#%+5V&$jVR@  %#&+55+55V;&Dj#5%+55%VuvA&(6R&  %+5+5\b?&H6  " %+5K@) iYzi  iY iY ?+?+9/_^]]]+99333310"6$3 ! 5!.267!3pZ+ ӕ [G SEnuH#X^sU@2 fY  `Y _Y ?+?+9/_^]_]]q+933310%267! #"=!.#"5>LYu To9-_iUqzp{ 𔂒&2,$V&jR@ . %1&+55+55X^&j. %+55V&jXR@ '&$ %+55+55&j $%+55^V&j-R@ <&'9!%+55+55N#&j ); %+559jI@& lY iY kY ?+?+99/+39333310 !!! '32654&+hP]h{Z\d O,5irf_9V^H@$  _Y ^Y ]Y ?+?+9/+39933333310 !5!#"'32654&+F\evbxP-3&MR&%+5+5#&Mu  %+5V&jR@ %&"%+55+55#&ju  %+55wV&2jR@ +&(%+55+55\&Rj , %+55w t@IiY*FVL!H I  iY  iY?+?+9/_^]q_]q++]]qq+99333310! ! 267! !.iQQeH7zmm|\s k@A{Y""#H"H9I]L   ]Y ]Y?+?+_^]9/_]_]]]q+++99333310!"&5!227!"!.>ndm1̍0ttpqwV&{jR@ .&+%+55+55\&|j ,%+55HV&j#R@ .&+ %+55+55J&j *%+55N&MFR@ &%+5+5&\M  %+5NV&jFR@ *&'%+55+55&\j ) %+55Ns&SR@ '&v$%+55+55!&\SR f& %+55mV&jVR@ )&& %+55+55{&j# % %+55VT /@ " iY jY?+?+?93310!!!!T+TLo^ 2@  `Y _Y?+?+9933310!!!!-^f^V&j5R@ -&*%+55+55-&j ) %+55/P&} H%++5)^o@=    Y   _Y  ]Y _Y ?+?+_^]+9/_^]3+39333333310"'5326=!#53!!!!3]G2033ω1L)3DQ@*        iY kY#?+?+??3999933333310"'532=# ! ! ! !RkM;;{:V;5N5BL)+ )^Q@*      _Y   _Y ?+??3+999933333310"'5326=# ! !!3]G2033{ZZ)3D;#dVg@<      iY)$IL> ?3?39/_]_]]+q3+39993333310!! !!!! !!q)V;5N'hN)j ^g@;     `Yo$ I ?3?39/+]]q3+39993333333103!!3#! !#fZZ.+dJ=\b 0@ iYiY?+?9/+99333104$!3!! #";\8{5VPh1JYefe\qG\&X@/ & &'(/ iY  ##iY?3+3?9/_^]+9/_^]93333104$!3!3265!#"&'#"&#"3265\* s5OVZN1l'+}H][Tb1BAfq-N=?Jil`fA;\ ,H@&* $$-. (]YaY!]Y?2++?+?99/93333310"323.5!326=!#"&''26754&#"^j 1PXWK-x>.Zofjqb(6&*fiKFfq=L7R!(T@- $)*/ lY&&!kY& iY?+?+9/+9/_^]93333103265!#"&54&+53 54&#"'6!2SUYO1ùXkqo$eYfq-jmNXdΐ9\s(\@5' )*'(('bY((P(`((( (( `Y  aY ?+?+9/_^]+9/93333102654&#"'>32326=!#"&54&+5erMOZxׄWK-8=66%".&9 'zfq̙efVsO@*  !lY  "kY jY ?+?+?9/+993333310!!!4&+53 54#"'6!2+ȶu*o$LjmѦdΐNo-s"]@2! #$!""!bY"" "" `Y _Y?+?+9/_^]+9933333102654&#"'>32!!!4&+5jzMPZwсoי8=66&!-'9 "}egFNI!:@ "#/  iY iY ?3+?+/_^]933103265!#"&5! #"'5326!OWZN2>_T@:35>7[ rwHCfq-=eaW ^5@  !`Y aYaY ?3++?+/9933210326=!#"&5# #"'5326!jPXWK- \|jD119M=/yJCfq O@R ? iYF!L;  iY ?+??39/_^]_]]]]_]q_q]q+_^]/_]933333103265!#"&'!!!!!=IUUI165}KFfq-=^d@;  `Y$ Hf$ I aY?+??39/_^]+_]]++/93333310!!326=!#"&'5!!2NQUI-k^RHCfqV3^wE@%iY  iY iY?+?+9/_^]+933310!! 4$3 .#"326=!5MkrhӚ5{gTk9*\sI@' Y ]Y ]Y?+?+9/_^]+99333310!! !2.#"!265!\E,\KH]*0V#'tc)b@@" / iY iY ?+?+3/_^]9333103265!#"&5!!!KVXL1sPs}KFfq-˾?/F^6@   `YaY?+?+3/933310!326=!#"&'!5=PXVL-^KFfqX(j@=&%% " ")*&kYV$ I*  iYiY?+?+9/_^]_]+]]+9933333104>32&#";#"32$7! $54675.v΅z릪 a̷`i[COwQKfXhaga1/OʒN%sb!@@#  "# iY iY iYkY#?+?+?+?+933310"'5326=!! #"'5326!!kM;<@:>_T@:35>7[ %VTLcaW J)^A@"   ! _Y _Y  `YaY?+?++?+99333210"'5326=!! #"'5326!3b[I4/33 \|jD119M=N)3Dy OR&$dD %+5VR;u&Dd#'%+5&$c#R@ %&+5+5V;&Dc  0#%+5&$t!R@ %&+55+55V&Dt)#%+55&$uR@ %&+55+55;&Du0*%+55J&$v!R@ '!%'&+55+55V&Dv<6%+55o 3{@  54%-@ H0!((@"H0@   iY ??39/+9_^]q]+q99/]339/+33993310!!!! &'#&'#567!".#"#>32326737jj{%!2ZSB0<,PG?,( } s`1QG=*) }r\D`|$GQJN`E;=!)/n~!,,syV;&Dw)#%+55Rs&$'KXRdD@& %%%+5+5+5VR; &D&Kd 15%(/%+5+5&$x)R@ %&+55+55V;&Dx1+%+55&$y'R@ %&+55+55V;&Dy1+%+55X&$z'R@ '!%$&+55+55V;&Dz<6%+55o 2@ 43,,,,$,@B H  / ''`p@   iY ??39/+9_^]]]q23/]33]]9/+33]]993310!!!! &' 3273#"&'%".#"#>32326737jj{%!jb -OG?,( } s`1QG=*) | r\D`|$;F/!)/n~!,,p|V;&D{/)%+55R}&$'NVRdD@& %%%+5+5+5VR;+&D'dN#'%2,%+5+5R&(d  %+5\Rbs&Hd %+5&(cR@ &$  %+5+5\b&Hc 8* %+5`&(RR@ & %+5+5\b&HR  , %+5&(tR@  %&+55+55\&Ht " %+55&(uR@ %&+55+55b&Hu )" %+55J&(vR@ %%%&+55+55\&Hv 5/ %+55o 1@ 32"+@ H.& & p@MH   iYF!L I iY iY?+?+9/_^]_]+]]_]q_q]q+_^]^]+]q99/^]339/+33933310)!!!!!#&'#567!".#"#>3232673J+ZSB0<,PG?,( } s`1QG=*) }r+GQJN`E;=!)/n~!,,sy\b&Hw #) %+55Rs&('KRd&@ %%+5+5+5\Tb!&H&Kd@ *. %!) %+5+5B&,cR@ &  %+5+5u<&c %+5BR&,d   %+5R&Ld %+5wR&2d %+5\Rs&Rd %+5w&2cR@ &$%+5+5\&Rc ( %+5w&2tR@ %&+55+55\ &Rt  %+55w&2uR@ #%#&+55+55&Ru'! %+55wJ&2vR@ /)%/&+55+55\&Rv3- %+55wo #;x@ =<-5$@ H$$8)00@#H_o  iY iY?+?+_^]q]+q99/]339/+33993310! ! 3 !"#&'#567!".#"#>3232673iQQeպs掍ZSB0<,PG?,( } s`1QG=*) }rzmm|YGQJN`E;=!)/n~!,,sy\&Rw !' %+55wRs&2'dKR@ #&%$,%+5+5+5\R!&R'dK  %(0 %+5+5ws&\vR@ V"%&&+5+5\!&]v} o#'%+5ws&\CdR@ !&%&&+5+5\!&]C'+%+5w&\cR@ 3+%"&+5+5\&]c )0#%+5w`&\RR@  ".%"&+5+5\&]R '3%+5wR&\d "%+5\R&]d #'%+5R^&8d  %+5R^&Xd  %+5^&8c^R@ &! %+5+5&Xc # %+5)s&^vR@ }!%%&+5+5s!&_v x# %+5)s&^CRz@ %%%&+5+5s!&_Cq#' %+5)&^cdR@ *%!&+5+5s&_c , %+5)`&^RR@ !-%!&+5+5s&_R3 #/ %+5R)&^d}! %+5Rs&_d#%+5R&<d  %+5^&\dV { %+5&<cR@  & %+5+5&\c % %+5`&<RR@  & %+5+5&\R ' %+5\ &B *+%+5! @  _  /]3210.'5!!.'5!F>"-!d)I-!d)17H892H8-9 !@@ H _/]399/+10#&'#567!'673#pcrapg;5YU5CK[eAN[nYu  %@@ H@  _  /]3999/+1067!#&'#7#&'53/pg<1~(arjiX@6SH,Ae`FwWpY- -@ O__/]399/]]29/310#'>54&#"5632#&'#567!!} 7B%+#%F^qȢpcrapg;5`r=t H)K[eAN1 %7@#"@ H@ H _/]39+2/+]3310#&'#567!".#"#>3232673厍ZSB0<,PG?,( } s`1QG=*) }rGQJN`E;=!)/n~!,,sy11@@H0p _  /]3]29/]+]10673#%#"&'332677F/\s àsXXr i`naNWS^L11@@H0p _  /]3]29/]+]10#&'53%#"&'33267je/F àsXXr Uz`i3WS^L1 C@+ @ H0@  p_/]3]22/]q+]29/310#'>54#"5632#"&'33267126k 3';5FVd àsXXr 4A)n )hCWS^L1 $7@#!@ H @ H   _  /]32+2/+]33103273#"&'%".#"#>3232673jb -OG?,( } s`1QG=*) | r;F/!)/n~!,,p| @   /?39333104&'3#"'5326NFOB#pJR<7#-4mB32%"32654&1 5ixkmplkp/&8RT@5H&@ iY iY ?+?+9310"'63 !"&'3254WId9_o`M:'gtp#(.w"G@'$  #$kYo iY iY ?+?+_^]+99333310"!27# 4$32>32&#".%o۴7_W.N98ddRMKjW rR':\!:@#"# ]Y ]Y]Y?+?+?+99333310 !254632&#".#"3267f ;+O>97eZH|>XKJ=- Ts%/2/$/u oF@%    iYiY?+?+39/_^]933310)#"#&5463! !#3 oe|b5A<øf`C/.55BH\b a@9  iY0   ]   s   iYiY?+?+9/_^]]_]_]_]q+99333310!!! $54$!3#";->=#qPhJ\dfc\q!E@$   "# `Y]Y]Y?+?+?+?999333310"323&=!5!#'#'26754&#"l ; hjumq{fqr2 (`쑥!\(C@"##)* &]Y _Y?+?+99993333310#"&'732654&'.5!2>54&#"mАy]XJI %wzgpzu-A-76.6iG]Ӷpkf{y p@E   iYF!L I  iY iY ?+?+9/_^]_]+]]_]q_q]q+933310!!5!!5!!yJyAJX%z@I$##   &'$kY1EV$ I*  kYkY?+?+9/_^]_]+]]qq_q+9933333104$32&#";#"!267! $54675$,΅zqj`LGYwYKc[`i2.O̖7V@2  iYY   I iY kY#?+?+9/_^]+^]]]+933210#"'53265!!!!鸲XL3>0<F=>3w&d@8(&$$ $'(kYo  &iY   iY "iY?+?+9/_^]+_^]+93333310!# !2>32&#"&#"327!DggW.N98diúad5 .%lb rDP13 8@"   !"nY#?+?39993332310!#"&5467!>74&'32?򍟆K< ?6 <%!% EFF橅fۄ05K(.?E-rL"E@$ #$]Y ]Y ?+?+???9933333103265!! &=4#"!!3632_de`1 wn1kһ~Z%Z% !@   iY ?+?93310327# I32&#"P6^qwEXA.4UBh^^~k8X#@@     ]Y?+?3?939933333107! !!4632&#"Ņ9XDϴTL98d`Tiìs B@#  `Y) ??9/]]]3+3933333103#!#53!馦Ϥ1\w!'w@F  ()0@ ##  aY aY?+?+?9399//_^]3399999333103''7.#"56327327#"&'&'#3H/24OW?3%L7!$r'n)r+ .!9=3 bm;3hb lwC4L =@  !"   iY?3+3??3399933310!3265!#'##"'##"&5!32655{s7+2rjq5|q/PJU[)/6@  kY #?+??399993333210)##"'53265!35!v JL3>0<{R}ͯ=>3vsww^#E@#  $% " "iY iY?+?3+3?939333310! ! 632!4&#"3 ! ]I;lgIm-K^|okz~*0\s%C@"  &'  # #]Y ]Y?+?3+3?93933310#"32632!4&#"32654&#"oV^r<-$doncdomd15/;yyyHv ^@4  !iYP iY?+3?9/_^]]+9/_^]9333310!#!#"#&5463! 32654&+5A<ø CgvC/.55B5pmmh+I@&$ )),- ]Y ]Y ']Y ?+?+?+?99993333103>32#"'#!4632&#""324& 2ihϳTL9801qhkte[QỦ>^;5>Nj!R3HV@+   iY iY??9/+39/_^]+9933333310!!3 !'32654&+6t*d^d~>1bihYV$<@ %&" iY"iY"?+?+999333310467>54&#"'632327!"$Vn/_[Se\}j6kjR9CG0CI-)gS3DJ/KT^\Ns"<@ #$  `Y _Y ?+?+999333310467>54&#"'632327#"&NVMEKRRއag,7A;:&)+.$XE&6.$fXONypX) E@&"!"YP  Y ]Y?+?+_^]+93323310"&5#"&5463 327";54&R7^J#4m+&6@42/7L R@)   !"@`Y ]Y _Y?+?+?+339933333310"'5326=#"&5#5?3!!327VM/38.X9I#f 9@     iY?+3?9/_^]93310)#"#&5463!!;ˉA<øDrC/*55B/7F@$   !]Y `Y ]Y?+?3+3?+9933333310%27#"&5#5754632&#"!!wPpreWKO>69I#3Xl!:9ZA>)y/@    iY kY #?+?+393310327# !!!<0>3_4sPs}?< i77!D@$   "# iYiY?+?3+3933333310%2654&'!!#"$547!!%ŁŪL\Ʒꕕ>^G(@iY??+?9933210)!>7>54&#"5632H9'7 ?+6&6"HbL':4&XeL0.#w.@    iY?+??99323102!!.#"56g@-N)41*($LkV-UN"#s 0@ !"  aY ]Y?+?+?93910367>32&#"!"'532?`.$"n1j,^&6K'لEO H!CC^_/u ]n ;V1q@W   iY]L*nL I iY  iY?+9?+99/_^]_]+]]]q]qqqq3+393310!!!3!!!5#wVRdd7^v@B  fY g<L   ^Y ^Y?+9?+99/_^]_]]3+3993333333310)5#5!7!5!3!!ס3BӮ #9jPD@$ lY iY kY ?+?+99/3+9333310#"3267! $54675!!{Хl[Okahmj6+OPX^S@+ _Y ^Y ]Y ?+?+99/_^]3+9933333310#"3267! 5475!!wȢd[P3-T"b-^#h@7  $%!Y   _Y $ ^Y`Y?+?+99/+39/_^]+9933333333104&+5!5!327#"&5%>4XNͼYq%?4(#\P$,. 875b@4   ! Y /   kYlY?+9?+9/_^]3+39333333310 !!5!5!>54&#"'>3235(jWMX^cPeAJWjBVVK0꺝9PE@# iYiY kY?+?+39/+9933333102!"&'32654)#!!PvJLd(' (7rlN#^M@( {Y  `Y ^Y?+?+39/_^]+9933333102!"&'53 54!##5!!DvAGZ)ì)&$2JL$H@## !%&!@!$!$`Y! _Y ?+?+339933333310#"&'532654&'.=#5?3!!+&6m_Yr@LSna,3kX188?6`&)977"3YRfs:@ aY]Y?+??/+999333310!33632">54&+k{i}xcoJ'ܢ|}@ #??93103#' fb@5   Y Y@#??99//]+33_^]]3+39333333310%!5!5!5!3!!!!#<<==Vu Hs&''=LR@& "%1*%+5+5+5 !&'']L@ "%8*%+5+5\!&G']L@ 2+%&%L"):%+5+5Rs&/- #%+5d&/M #%+55P&OMq P %+55Ro&1- \%+5`&1M \(%+55!&QMB M -%+55&$LVm@ %&+5+5V;!&DL +$%+5A&,L"m@ &  %+5+5!&L  %+5w&2Lm@ &%+5+5\!&RL # %+5^&8Lm@ & %+5+5!&XL3  %+5^)&8 LR@,& %+555+555&X L@  %+555^^&8R@1& %+555+555 &X@  %+555^`&8 KR@(&92 %+555+555&X K@ ;4 %+555^^&8R@ 1&. %+555+555 &X0 %+555X^sU@2 fY  `Y _Y ?+?+9/_^]_]]q+933310%267! #"=!.#"5>LYu To9-_iUqzp{ 𔂒&2,$)&$ LR@$%'&+555+555V;&D Lw'9%+555)&$ O@ %&+55+55V;&D Nw&%%+55%&MRy@ %&+5+5V&M=ʹ<;%+5w!@^!  "#? mY ! !! !!Y @ H iY  lY ?+_^]?+9/+_^]+_^]_^]q9/q3+_^]3993333333310!3## !2&#"!275!5!5!DggcX^.%lbZPZc\s -{@E ++$ $ ./ Y !`Y  @ H(]YbY?+?+?/+_^]_]+99/3+399933333310!"'53267!5!57##"53237!326=4&#"XZDHmM lv{}hn|klkBV-0q%}w's&*LR@  &E$%+5+5\q!&JL0(&%+5Ps&.L\R&Ŵ%+5+5&NLF{& %+5+5w&2Q` !%+5\s&RQ%  %+5w&2'Q`Mm@+&!%+*%+5+5+5\&R&M Q@ )$ % %+5+59jq&LP@ "%&+5+59V!&L#%+5 H&'= 1%+5 &'] 8%+5\&G] L" +%+5w's&*v3R@ #& %+5+5\q!&Jv; A(,&%+5@M  iYF!L;  kY ?+??39/_^]_]]]]_]q_q]q+_^]?933333103265!! &=!!!!!WffX5 65߄v}h=:@ jY#iY?+??/+999333310!33>32"654&1BmhcpMUgˉs&1C}R&%+5+5!&QC %+5s&$sR@ %%!&+55+55V;!&Ds .-,%+55}&$R@ %&+5+5V;+&Dq#)%+5Ps&(sR& %+55+55\b!&Hs*% %+55}&(\R&  %+5+5\b+&Hm " %+5ss&,sR@ 5%&+55+55 t!&s %+55}&,R&  %+5+5+&7 %+5ws&2sR)&$%+55+55\!&Rs(# %+55w}&2/R@ #&%+5+5\+&Ry  %+5qHs&5sRt@ $ %*&+55+55w!&Us %+55H}&5R@  %$&+5+5+&U  %+5^s&8sR&&! %+55+55!&Xs# %+55^}&8R@  & %+5+5+&X  %+5^1s'l@?  !()`YE#  ]Y%]Y?+?+9/_^]_]]]]]_]+99333310%4&+532654#"'6!2#"'326ȷJHZ Yi{di'!aз% ɢyP+5fs&+LR@ &  %+5+5&KL9{@ & %+5+5h3@     #iY?+???99933310!4&#"!33>32h}1Dfm\NEm"V@-  #$!!iY iY?3?+9/_^]+99933333310! 5467.=!! 5!! ! qgtrg5-)6A^_/;v<9J\'L@'# ## ()&&]Y  !]Y ?+?39/+99933333310!".5%.=!326=!324&#"olrof1VbcW2$v|v|H46Ԟ:r3īʟ#1q&=}H  %+57)^f&$OR@ %&+5+5V;&DO1#'%+5&(z  %+5\bs&Hz +*+ %+5w)&2 L/R@/&%+555+555\&R Ly@  %+555w)&2 M/R@ &+%+55+55\&R My #/ %+55wf&2OR@ &%+5+5\&RO? %+5w)&2 O/ %+55\&R Ny  %+55&<MR@  & %+5+5&\M  %+5N{T@.    @YO  Y ?+?_^]+9993333310!>32#"''67.52654#"1T,S/@*-1`D9 C#XJy=#rB-%R2r)s&/k@< !..#**#&!01# @  ]Y,YO 'Y?+_^]+?+??999933333104&#"!33>32>32#"''67.52654#"NMUtg)-nT,S/@*-1`D9 yy^NVC#XJy=#rB-%R2r/L&n@<! %%!!'( @  `Y #Y O    Y?+_^]+?+333/999333333310#5?3!!>32#"''67.52654#"X9T+S/@*-1`D9 yfXC#XJy=#rB-%R2r\T)6S@, ..& 44&78  *]Y1##]Y?3+3?3+3?993333310323&5!3632# '!""326=4&!"32654&\k 2 kwyapklpelynmgnlkp/5|aj8μ/d55\Ts)6S@+4' - 78  #11]Y**]Y?3+3?3+3?99333333310#"'#!47##"326!22654&#"!26=4&#"Th hx~apinoflolepnip/Υ4`^2355ff@5       " @  iY   ??39/3+3_^]9933333332310!!##!!7&'%3X{jǯ6jo!F>uN\ XLCYwf%g@8 !#$$#&'@#)H@iY"&@#  iY?+33_^]?3+3+933333310&'327#"'#7&54$327"&-.AdV"<۴SF2E7ADk3&cMK RYW Svq\V1"\@0$  #$ "  ]Y ]Y?+3?+3??9993333333310"'#&!23'3267f51Ǧ ,(Ĥ3ZLXKJ#ysdz-4/2/$?M1/? z@K   iY]L*nL I   iY ?+?9/_^]_]+]]]q]qqqq3+39933333103!3#!!#/6QyRdT)fU@-    !"@  iY?+333?_^]^]933333310!!73#!57#/s13ʋddB ^bDo\s5L@() /$$67/$''-`Y'_Y]Y?+?+?+99933333310327#".'./53254.'.54632.#"$TGF7!j/ba9'G@3UQ,lZy7ʿ\TLWz:L &,QA :taP(6`$-9&6\wWX$.I)<;5\x7^E@#bY^Y ]Y?+?+9?+99933331035!5!327#"&'.#7BV00ZGI<#n1<$eZ7vrqX gM-@   kY?+?9/39933310!>54&#"'632ϴsXm !a=|Unb}s-@   ]Y?+?9/39933310!>54&#"'>32ϳsXmdـǭ^D=}Unb7F(@ & ""&&)*! z*Z8  kYF$IL: iY1"%""" "iY?+_^]_]]_]?+9/_^]]q]]]]+]qq+_^]99/_^]33^]]]q39333333333310#53! #!32654&+3#32654!7{f{6~q{ʀz\ sNZTIZ\be ]@1    iY_   iY ?+?39/_^]]]33+339933333323103## =#53!!26=!^Ȯ5Fߘ!:mo3if@s     !"@iYF!L I  iY iY?+3?3+39/_^]_]+]]_]q_q]q3+3_^]^]9933333333310)#7#!733#3#!3#7#N''H=RaqR??^^wA\Vb$(,@[)+,(# %%' $#,+ -. +)'")) ")fY(""L"\""" "  _Y `Y?+?+_^]??9/_]]]3+_^]399999333333333310"'#.5323!3267"37&'7[AǨq*,Ǧr{D\"3^5K'TU?< ixg]@\Ns)I@&+' !*+  %]Y^Y]Y?+?+?+?9993333310"3237!327# 547#726754&#"j<934=>} 1tlo{k14PT%9BiLZnQT%HU@, iYiY?+?39/_^]3+3399333333310!#53! !'32654&+ʤ*d^11݁91bihXwsZ@2    Y  dY ???+9/_^]3+39933332102&#"3#!#5333>>)%5yϠ-4s ha9Ѽ^sX@0      qYI   ??399/]]33+339333233310!7!3#!#53'!7#bNkkhhP/j /^"o@;$ #$ Y:/ ""]Y?+?3939/_^]]33+33993333333323103!!!3##"'5326?#6?#oNnmG}iAOL7AQy"8 !# JJ# cd7Fg[eeRps"Y@/ #$  eY_Y_Y?+?+?9/_^]+_^]9993333103>32327#"&57>54#"o;P®e/vj^cI 1RdXZze\qs:@   ]Y^Y?+?+??999933310"3237!#'#'26=4&#"o; hj}jo}fq23!s>@    ^Y]Y?+?+??99993333102#"'#!336"3265k +kjv|cnsУ^?N)C@"' ' '*+  ]Y]Y$]Y?+?+?+?9999333102#"'##4632&#"36"32654&p3鳳TL9801 kpqhkt^opsЏ{5>[!?s&@  ]Y]Y?+?+9310"&'32654&#"'63 nIF_rxdW%./2BL\#s(R@+ &&)* @Y ]Y #_Y ?+?+9/_^]+9333310632#"''67&5!2.#""32654& v+!Di#ZFvB4hAG[@+&4yOSUD[|,L&nZ91,2\N+M@(-) " ,- &]Y]Y]Y?+?+?+?99933333310"323&5!327# 5467#'26754&#"o 2934=>}  hjumo}fqr23}bfo9BiL7f+!\N#)G@%+' *+]Y$]Y]Y?+?+?+?999333310"323&=4632&#"#'#'26754&#"o `L961=; hjumo}fqr23}b=>L!X^s\@5  fYL\ _Y`Y?+?+_^]9/_]]]+_^]933310"!."&'53267!5432Lcp mJ`e/|puwR)&.*X^s\s!(k@9 *& %% )*bY %& &   `Y"_Y?+?+99//3399999/_^]+9333310"&'!"5%.#"5>327327265e(uckX{%13-BKCm4o}=qLo ti&2,$5jjB5TyR\N%sN#sNs3@U5. ("..2(45 bY& 2332{Yk3Y333t3b33<33 3 33& `Y &,^Y&?+?+9/_^]_]]]q]qq+99/+999333333102654#"'>3273267#"'# '53 54&+5GLZrӈ4s3-+CCm~K:nu~SXl7:p&!-'TLkjB TN "}efVE*,DA\s(|@I #'##)* '(('{Yi(X(( (}(l((<(( ( ((`Y ^Y?+?+9/_^]_]_]]q]qq+99333333104$32# 2654&#"32654&+5\msy!zwbnys'1]x u]25F1?H?@5}q^=@   Y ]Y?+?9/3+3933322310"'53265#53!3#FuTFIMG1VT#@\N#&2S@,!40 ** 34 #]Y.]Y'^Y_Y?+?+?+?+99933333310!"'532=7##"323&=4632&#"26754&#"qkv`L961=xgo{kBV6 3}b=>'%\qs &F@%  $'(#!%!]Y!^Y_Y?+?+?+?999333310%26=4&#"!"'532=7##"3237!o{jo{ks kvۍ%BV6 3\PsU@.fY  ]Y  ]Y?+_^]?+9/_^]_]+99333310!! 4$32.#"!275#VkcZ>S?DyX)(. ,^ 8@"!"  eY?+?39993332310467!367!#"&%4&'320Qd?$ 5?Th"$% EFO{'$Acm,ED*rs-7D@# 9#20..0890' !'!]Y'5eY?+?3+399933323106?>32&#"#"&5467'.#"5>324'326P/-H>yK]$(&&E.(>3N+"&YW6z&GEF$"#"T3!32673#'!&Jt#1%+ n)k!49=N@)  Y    Y??9/3+3_^]+93333233103#!#"&54632!";54uH~i?21w#%b>Vqljz%"e#Ci !@  ]Y?+?93310327#"&5!934=>|1}9Ba@4  _Y ^Y ]Y ?+?+9??9/_^]3+9333333310!#"'32654&+5!!!E\ew1^bߗwP-3;^#=@# #$%    ]Y?3+3??3399933310!3265!#'##"'##"&5!3265R1QWuj1)0jX,l1QWpo^syyOTLWsyy;^$@@   $!! %& !]Y?3+3??339993333310%#"'##"&5!3265!3265!!47 hX,l1QWpo1QWuj1 LWsyy1syy=kBs-J@& && ./   *]Y#]Y?+?3+3?3?999333310)4&#"!33>323>32#"'532654&#"QWuj)-nY-nükM;<@:QWpoyy^MWNVVTyys6@ ]Y ]Y ?+?+??99933210)4&#"#"'5326533>32V^rr>=33:)3ryyyB9ۏQSs:@    ]Y]Y?+?+??99933310327#"&54&#"!33>32934=>|V^r)3r}9Byy^QS#^(@  ?3?39993310!!!.5#n^mB^G5\s\s#@K $%  Y:/ ^Y`Y !]Y ]Y?+?+?+?+9/_^]q_]]+_^]99933333310)5#"&5!25!!!!!32654&#"^b1m{zkl{zl';-8#H^Ds'L@( " ()     ]Y %^Y?3+3?+9/_^]9933310"&'##"54$324&#"326=!326z* RYU7TLLTXVhj +sŇs\'+^)@  dY  ???+99310"'3265!#'#33#71-4 9]s+)@    dY ???+9993310"'3265!#'#33#71-4 ]s+^8@  dY ]Y?+??+9933310%#"'3265!327#"&=47| ^` 9%9B;hws+@  dY  ???+99933102&#"!33>>)%5-4s J^sws2@dY ]Y?+??+99933102&#"327#"&533>>)%5934=>|-4s J9B^sw @  aY?+?993103!2&#"}vw#D=!1+w @  aY?+?993104#"'63 d=D#ww}!h5^I@%    bY   bY ?+?39/_^]+39933333104&+326#!!2!NWMͰXiӞJ;JN`^S)^I@%    bY  bY?+?39/_^]+39933333104&+326!#!!3NiXMW;N1\GOJ=)S⡱^`\s/L@)# )01)!!'`Y!_Y _Y?+?+?+993333310#"'327# 3254.'.54632.#"C:.704H^UQ,lZy7ʿ\TLWz:L::R(6`$-9&6\wWX$.I)<;5\x#(@ ]Y]Y?+?+932310#"'532654632&#"ѱr>=33:`L961=yB9;=>#P@)!  !`Y ]Y ]Y?+?+9/_^]3+393332233103##"'53265#534632&#"Ѡr>=33:`L961=B9yݻ=>s(@ ]Y]Y?+?+9323104&#"5632327#"&5=2;3Hd934=>r>=u9BF#$X@0&" %& ]YY  Y?+_^]?_^]3+3?+993332331034632&#"3##"&546326=#"`L961= (0189(=>Lly25?6&+BJ`h@B    `Y/o ]Y_0P0/]q]+?9/_^]q+3399333310"56323#5!5!4&PprX9Im#3fA>/7L@@  @  `Y]Y?+?+339933331027#"&5#5?3!!wPptX9I#4fA>B^b@3!   !  eY    ]Y?+??39/_^]33+33993333332310!'##"&=#53!!!3#%267!)1sȚ11kyZVNUdRR}yy3^F@$     `Y^Y?+?3+399933333310%2654&'5!#! 57#5!jmcdpiٚBFԀ As/@ ]Y ]Y?+??+9933310! !32654&#"56321omo852=To`;B^ @     ??393310 !&'#!'%^}bi|^^"@ ?33?3999103!!&'#!.'#!VuH>т .) *B^yu_#8G>^)@    ]Y ?+?393992310)&'#!>32&#"  AXD5DQy"JKwg[î cd7^"@  ??39932310!!!RXX^X7s^J@'    ^Y   ^Y_Y?+?+9?+99333310"&=!5!5!!327ŊB 3321LQB47N^ Z@.    !"Y ^Y    ^Y?3+92?+99/+933333310!'67!5!5!3>32#7254&#"h4J{]|q! 0F&}598ACoP#KE9V^V^#/~@G'-  "-01$eY  bY  O    ^Y*_Y?+3?+99/_^]+39/_^]+93333332310%4&+5!5!&'#"&546326"3267.!fFt=4L0"Uzxk;54&#"'632϶sXm sa>{Unb}1/@  ]Y?+?9/399333104>32&#"!.1yۍmWtϺh~o}bmV{>oU-@   ]Y?+?9/39933310#"&'732654&'!|nrmWt³1}q9CcmV|=V\s(@ ]Y]Y?+?+993310 !2.# !267hšZV^-HML(.3Tw&2y %+5^Ns$|@I !  %& $${Yi$X$$ $}$l$$<$$ $ $$`Y^Y?+?+9/_^]_]_]]q]qq+9933333310!"$54675&54$3 #"3 !"3u#;%on!`q1Ѵa ,ԡ6C?DZ`;9D3\&]@3!(  & '( fY    #]Y]Y]Y?+?+?+9/_^]_]+93333310.#"!275#5!! 4$3254632&#">S?DEIO>97e1 ,X)Zs^F\#j@;! $% cYY Y?+_^]?_^]3+3??+_^]_]99333332310!3##"&546;432#"26=#"1 8 SSK(0189(^lyGO25?6&+V^7@    ???39393333310! !7!!71)`B1y`=kQT%O@' eY  ]Y ?+?9/39/3+399333333310>54&#"'6323#!#53sXm ϸ>{Unb}a1M@& eY ]Y?+?9/39/3+3993333333104>32&#"3#!#535.1yۍmWtݺh~o}bmV{>ƊU\$'d@6"&&'()&^Y%%^Y  ]Y ]Y?+?+99??+9?+9933333310)'##"323&5!!!26754&#"; ho 2K  umo}fqrn23}bfJQ !Z\9-:@F"8 1-))-1 ;<,_Y 5]Y^Y.]Y &]Y ?+?+?+9?+99??9/+39333333333310 !#'##"323&5!!#"'32654&+26754&#"; ho 2F\ewoumo}fqr23}bfJbwP-3>!\N%25>@J5!8044 )>!88!)?@";Y" $33^Y>4""^Y"-]Y&]Y?+?+?+9?+999?9/+93333333333310"323&5!!3>32+'67!'#'26754&#"254&#"o 2TzazoϞ4; hjumo}fqrn! 0F&23}bfJCq}598A!ZtP#KE/9L 0^@2 !!/&&/-12& `Y  @ 0 0`Y #`Y?+?+33?+9933333310!"&5#5?3!632.#"#3!254.'.547!X]Sʿ\SK%]gz9$bk fX$.I%/'3[xRj_"&0+F{*/F%-^@1 /+++(  ./"]Y@**`Y&]Y]Y?+?+?+33?+993333333310#"'5326=#"&5#5?3!54632&#"27!hr>=439rXE`L961>PpIyB93f\=>/#wA>/L0;@G -&$+//$4::$<=4!11Y]Y*+@(+%.+.`Y+!]Y!7_Y?+?+?+33?+9/+999993333333310%267&5!2.#"632# '#"&5#5?3!!%"3265469'#[YZEwB~dmX%57cFF[-'\,"*&'#iQPf녴60(:91^)1i@7'%'/23(+!]Y+ ]Y+%%`Y%]Y?+?+33?+?+?3993333333310"'532654#"!!!#5754632&#"!3>32kM;<@:qϨϞ{N\NA:)1rʼVT۫yyRR/M} 6wX83L`V^r1}9Bi#dUP{yy-@     TW?3?39?99333310#4#"#33632fW O괆w?{3@     TW?3?3?3999333310#4&#"#4632&#"3632CJfW>A--N QY[wVsX`nnq!@  V TW?2??9993102&#"#33>4.r# ,peVFIS1ym#@  V TU?2??99310"'732653#'#2 /r# ,ypeJQ-8@  @P VU?3?/]39933310#"'732653327# 547{-L2 .rN*.0a EHpe\\-U_8@    VT?3?39/399933333104&+326!#!33REA@/a{6;:jAzF'd@ VT??99910#!33>7!3>73dXE&0Je kf !iF.!n'$#3s*@   @ P  V?2/]393910!367!#"'532?  3G2"<5)3_GKP )w  +)u '@   / O _  /]q33/31044#5266*nn*6-3hm3+)u '@ /O_ /]q33/3103"&5463"6*nn*6-3mi3`!)@   ?33/9/399333105654&#"'632;6UWDq+p0;7@Ch!q!+@ ?33/9/399333105&54632&#"󫚚qDWU6;h;ɀ@7;0p+,@[/10%5% V@Hx,@[/10-5,VxHV1H/10 #3vHVVV1H/10#31HvHV+)X!vX!C+JH+]5+dM@_P]q5^XC @ H@Pp]q+5^Xv @ H@Pp]q+5+J @/?99//]]10 !lJ+-J@ /9/]10 J+)F+)F+V+V+-+7/3105!+{{LF3@o  0/]]33/]310%327#"&'4,BKDmf(RNhgE5To13@@$  ! @P V?3/]99393333310746733673#"&%4'328.  *d~glw575K\^4If`RtcxybRd3`V@ T??9310#3jy$/@  %& W U?3?3999333310#"&'53254.'.54632.#"ZDBD!RLbHAt:kJni^-)G"+7pamzA#7.*)EZ+ /@     V T?3?3999333310 !! ! !T+3 fTD!*@ T??39/399333104632&#"#.DѧToE[ٓ\IPA[/A@ /3/99310!#!5!o @  //9/3993310!#!5!3oR$@ //9/]3993310!#!5!3o^ @  //9/3993310!#!5!3oV@ //399310)5!3@ //3993103!!$@ //9/]39933103!!#odiL& @ H@  @ P p  ]q+5P]w +H/+3?910#3dۢ%9+H/+?29103# +#d%=/@@H/+]?10%5% Ndۍ/@@H/+]?1075-N/d܎?XCf?S{f? +@?  O      /]qr]qr3210.'5!!.'5!Q-n?Y-;?;2)W@.rY R#H@ HP]++5uks@ `/22/]10!##Tmsmks@ `/33/]10#5#5kmsmk; /22/1033mTmk; /33/10!5353kmm)V@  /]33/]310!3!53nsuVR)V /]210!3!nsVR) /33310 5!!+Rdy{N!KUMVE@4=/O@$H@ H/++]qr^]_^]210!!VVw+N[OYjcPC!SN!Lf) ?10#f)d)?3210#!#H()ddj 5@O_o  @ H _/]33+/]3]210#"&'33267%4632#"&j àsXXq F;9JJ9;F+WS\N+?>>?32#.#"w ۨ .SX ٗ/6}=$=$= $=$_!C @ H@Pp]q+5_!v @ H@Pp]q+5LB H/+9/310353#5#ᇇᾅ{LB H/+9/310##33ᇇDžmj@ _/]210!#!ڈjgFP3 /33/10>5!dN-#w{  /33/310463"3"&}r*600qi~0**0~)V@ /]3/]33103!535DRb{{)V@ /]333/]105#5!#DV{{)- -@      /q33322/]/]q]1053533##5ד{{UtM@ Pp]59j  _Y?+/10"'532653XL12517?j  _Y?+/10"&533273321LB4rY~jz@  P  ]q55 @   H /+3]210#"&546324&#"326moqo5++5`+5h~hg~d*00*Z0U;9zC6Q,KfH+]5Bm//]2/310!#5!#ڈ6b}& @ H /]3/+33310#"'#"&53326533265wjo55ohwop3@bs3@}q|GGzsBEBENiL& @ H@  @ P p  ]q+5NgK$ @ H@  @ P p  ]q+5wGNn @ H  P p  ]q+5wGn @ H  P p  ]q+5cYR#H@ HP]++5UeM@_P]q5!H/310!5!BY1]aRV.HH@ H0p]q+++5 /210!! +hP/10 djoV ?/10 #ou}  /33/310#526544}q006*qj~0**0~Bm@ o/33/]310!3!53m&ʈB\5-@  0/33/]310!!35#fٴ-}$ @ H /]333+22104632632#4#"#4#"}wjo56nhwnq3@bs3?q|HHzsBEBE/3 (@ ? O o  / O _   @H /+]q1077''7V{yX{{Xy{VyX{{Xy{VyyV{}%@/O_/]q]10463"#52654.r<;%+%t<;%+%FK]g.5>G(L^h,8>EV#@@ H/?o/]33/+]310!5!5!5!TT;|!C!v:cRUp8?5mxU@ @H+]555B!@`p_/]33/]210!#5!#B|Y1]KH+]55B@ _/]22/]10!#5#|{w-8@! / /]2/]3//999910"''7&#"#>32732673?MIeJ$,*} ucGCEeF""+* }s){32326734632#"&4632#"&.TLD,*} x`3UIA +* }sF;9JJ9;FF;9JJ9;F#+#7>?>?3232673".#"#>3232673+ME=*& } p\0OD<)& } o]+ME=*& } o]0OD<)& } o!*.l!-+qz!*.k!-,rz?f  /33310%35 5#F /]9/3105#7#Bxx% !'/7AIS]gqy@w  &$622?2O2_2?O[ooVjv~~rzB88F< QeeL` .*0*@**$2jz<`**`32#.#"#"&54632 à sXYrTF;9JJ9;FWS^L+?>>?73#&'##567&'5 YRh,:,!hd/_'nO39CT2=323273#".Kh,J9666l")"?H )@X@P / _   /]33/]2]10 #&$# #6$dCQT[aHaj?+/22310!5 5!2ξы)F @ X [Y?3?3?9/3910'#"&546?4#"'>32%326=\u}bVBBcC. MYb5o{ujmn t= 2E&#RA% )R@@ H [Y?3?39/+310"!."&54632!327 ;LI$ȶ'^U~|:qyHNFP]Q]85o @/ Z X??]210432#"#3mommo^^\)T  [Y?3?310#"&5463232654&#"T#AHG@@GHAŨťeddedbb)T@  ZX Y?3??3910'##"&5332653 wKwQL5Z06|di~LA)% [Y?2?310 4632&#"327/un323>32#4#"doMFə sF=tGnPB5i~Z06f/7z5ke5@ Z X[?2??9102&#"#33>,)^mɘ %v]Uw>E)T@  ZX Y?3??3910'##"&5332653 wKwQL5Z06|di~LA5  ZX??391033673fэ5pKF;VA5} @  Z X?3?39910 373#'#䏏㚜X)o   ?9910>7!#) P/+E5DF>)= @  /]9910!5>73"P+E9AF>?sC\s&FO@ 0pA %+]5?s&COƴ %+5?sZ#/j@'--01_Y@) H*Y0@p  $Y ]Y ?+?+9/_^]q+++9333310>32# !2#"24&#""32654&/=fN%ȠahXk~:r!"h5GFABN\ǟ~iÐx~ h}A72&)-%'QT(@?Pִ%+5]q5V&QjR@ +&(%+55+55\'^)U@- ( " ( *+ _Y %bY _Y?+?+?+??999333333210"'5326=$47!654#"'632!327WM2070)NV+%1Dj HZ/+7?7VtS\ZXVpw9@  iY  iY ?+?9/+3933310!$! 32654&#"mMOgսj$$:#=ڪ\s5@   ]Y `Y?3+?+?933310!&5!232654&#"ʼϸm{zkl{zl1+,(0w2@   kY iY?+?9/+9933310";!&5!2.%glBdRɲ),Eg':\Z's%<@'  &'#  _Y ]Y?+/+99993333104$32&#"#"&'532654&'.\ֹZ#FkG?_c[bNg$PBES2 /!3>-4, [@2   iYY   IiY?+?9/_^]+^]]]+9/99333310)!!!!5#N^ N@(      `Y `Y?+?9/_^]+9/_^]99333310!!!!#5#?J/#b@6 !!!$%iY$IjH   lY lY?+?+9/_^]]]++993333333210!654&#"'632!327#"&547hŅ0 ,(3Ou-;+#13Ka!wV/#ySjV'p^m\ #&P@* %"'(%&@ _Y _Y ?+?+9/9933333310327#"&5475654&#"'632% 5923No!/43Ox"bbG8<4O])PB? #~UdD}FG@&        iY?+?99//_^]99333210!5'%&''%&#"'6! Zq(f\Ru OWH;9-%gS5PkOWfA@"      ??399//9993333210%4''%&''%&%!w8!5{:TeQVLǦbB{~coc'<~[)G@$$   *+  iY $%iY$#?+?3+3?339993333310%##"&'##"&5!3265!3265!)!2> s㈸5 5y5Ç5É}5^j[mB\B5^_;^)G@$% ! *+   ]Y %&`Y%?+?3+3?339993333310%##"'##"&5!3265!3265!)5!27 hX,l1QWpo1QWuj1\ LWsyy1syy\!@@ ! "# jYjY?+??9/+9993333310.#"32>5!!47##"432#>+aqyto?4 >ŀDk; {_¶3J/`\j\qs>@ ]Y ^Y?+??+?9993333310&#"3265!!47##"32"Rcof2 kBRo =k++9@  jY jY#???+9/+99333310"!!63 #"'3254.OB6j}2G!\-//e Z^7@  aY aY?+??9/+99333310%#"'32654&#"!!632Z唎r-y1u|201N`w3ê?^\#V)M@)% *+ ' iY'"iY'?+?+9/_^]99333310467>54&#".54$32327!"$VoQTOW!ρi3kjIHbVBTUS*&i'q1çG+:H0KT^\1s,O@+'!-.! * `Y*#_Y*?+?+9/_^]993333104>7>54&#"&546323267#"$1Mwb1[KH\+JL}]2`fez-qM:PeEQRRMQO\sγ|E=K\;,40&9 ]@/    kY iY?+99?+99999993333333107'&#"'632>32&#"! !9>Y,6BW]^<6XW`D--2A/qZ})Oa^R)E6H1^]@/    _Y `Y?+99?3+3999993333333107.#"'632>32&#"!!':&028G[^t25sX[G721C5{`B1;DE:VDw#T@. !! $% iY  iY iY ?+?+9/_^]+999333310"3>3 ! ! &2654&#"NJ,m`Iiƨż˳R\fXiT%|\s"`@6  #$9/ Y`   ]Y]Y?+?+_^]9/_]+_^]_]99333310 32.# !2654&#"5632*tXIQ`qZT3u/r+ ?$,'-TJBK)L#!O@+  "#    !iY???3+39/_^]393333310)#"#.546;!32#654&+;uA<5rccH-"_I) ;V5C233*7\sF}Mw{\sJsw&4@   ?3?39/999333310 #!!3!!4#/ } {vXDJslY^ -@   ?3??9/9993310)#!! !mJLs$Q@* " "" %& eY ]Y]Y?+?+?9/3+39333333210#"'#!!!5#5332%"32654&ښ\yyqj+t323g2.+ ?ni:pwN6) 4;2bt6&-&w4\qsT:^Zf^ 9@#    gY/ ? _ o  ??39/]+9910!!!! '`TaT)ma5 ^5Lg^@U   gYv   d   $H   gY  gYgY?+?+3?9/_^]+9/_^]+_]]q]+9333310)!#!!!!!!#VwHe/'b^Xu(28@7 %6) -- 59:) gY)@%H) )6fY"H@"H /_Y#`Y_Y3_Y?3++?3++9/_^]++_]q+_^]++999333333102>32327#"'#"=!.#"5>7>54#"27!%HdÞYMcsBxĸYq||czRiufixW TEBNdA@ꔂX,$W[zfo|H^&x@F " "'( gY wf$H &gYgY?+?+9/_^]+_]]q]q33+339333333103!23##!#!32654&#'32654&+d7Te^ef`\ag/U;kLOJF;FB9ys&@ gY gY ?+?+9310"!267#"32&HSPʹ 9+ 8NHd^(@    gY gY?+?+993310)! !#3 di7h`9^m!Fd^ r@B    gY~ m$H  gY gY ?+?+9/_^]+_]_]q]3+399333333103! )#%!#3#3 Fji7j$h`fmD^ a@;   gYvd$H gY gY?+?+9/_^]+_]]q]+933310)!!!!!Dl^{^Vo'q@C"  ()gYvd>N  %%gY% gY ?+?+9/_^]_]]]q]+993333310#"'532654&+532654&#"'>32ISm`hikiքXhq="&VRJODQ;DZ@9J^ >@#   cYP`p  ??]q+_^]_]933310#"54632!!ݦSS1ߕGO^ $@ gYP` ?/]+93210"'5326539Q>=6NE]hH^ 6@     ?3?3939333310)#37!Hh`5pEb^ u+{^ P@,     @ gY?+?9/_^]^]99933333103'737!5Xq\qT%iAww^4@   ?22?399933333310!##!3!#47# JJ s^\n^,@   ?3?39999333310)##!3&533 Tt^Hyo (@  gY gY?+?+993310! ! ! !  !"1,'}}Ho&@ gY gY ?+?+9310"'632#"'532654&Ey9PRE+N9 ɶ\D &@  Y Y/+/+9933102654&#" # 46$4ό?m{zkl{zl \-@  Y/+/9/933310! '>54! !.\>+K%2./% ĘZH|>_FK%?#Q@.!  $% Y Y/+/+9993333310% 47'76! '"654&27-dhe/3RlTcCR;1!zoDDr57.=zk3 5&6zlXws+2@(&0& /340fY"H@#H #]Y`Y )]Y ,_Y?+?+?3++9/_^]++_]q+999333333310 632!"&'#"=!5.#"5>4&#"326267!-pGdmZl{zkl{zkcv >tsNM &2,$vun}u5^"V@.  #$!!gYgY?+?39/_^]+99933333310#"&5467.=332=33254#"CT`dLIme.Wi-(tυ!\'s@  ]Y?+/39910!54&#"!5!2l{zl' 0\' @  ]Y?+/39910%267!#"!{xk87pᥡ7^<@   gY   gY?+?9/_^]+993331032654&++#!2Rlq\en%hoPWUSQo^^ I@&    gY    gY ?+?39/_^]+9993333310 !.5463!##";5E`hty^gdgsN$oBNKV^ ?@    gY  gY?+?39/+99933333103!"&5467!#";fb sgdym'RWM+^%@ gY?+3?9310!#!5!!T`^%@    ]Y?+?3993310 !3265!1irbe1`jN+3<@   Y Y  /]+9/+9933333107!2654&#!!#Nyy^QS+1V^r1)3rD+d3 ,@& *!&&!-.  @) H/@ H!+!"Y!*++*Y++/]+9/+99//+_^]3+]393333333310#"&54632#"&54632%#!!2654&#!!^IBBKLAAJIDBKLA71{| , +^^^"'7)7^"@    ?3?3399910).'!3673>3%$ '! 'V9*J^$5j{L~V^ ;@ gYgY?+9?+999333310)5!5!!%83D^X@1 gYo gY gY ?+?+99/_^]+393333310!5!#"'532654&+ZʘKT` ="&SYOKdRo%<@!&'# gY#gY#?+?+999333310467>54&#"'632327#"&dBKHAQG=priP(TT-rA:-3%19!!NRyY.,39$;BFEo!2@  "# gY?3+3?999310327#"&'#"'53267.54632Db-Q.1bfm^bb35D6bCwiӬkRXL Vxc MU~nęj^@gY?+?99310!#^b^%^ @    ??399910#!#.+  +"Z^*9^%@ gY?+?3993310!#!#!9Zb^^m?^@@   gY ??339/+3393333310+##"&53;332653?&&vyHwfZlo/^)@ gY gY?+?+?99310!#! #"'532>!/EJvA3-)).)E tD 6@   ?  NI??39/]3999333310'!#! '%N}Nyy}o~:dDg@=   A 3    Y H  ?N IN?3?33?9/]39/]]q]]q_q39333310!5!#!!!!!%!#DlXfp]߰ `@8 !"N:$HHXIN?3?29/]q+]q_q]39933333310!2#!32654&+32654#JVNdZϸs[SYaw]YyWvwcg6>;2sDF $d@:  %& N:$HHX$IN?3?39/]q+]q_q]333339333333103!23##!#!32654#'32654&+J:7ϸss]Y[SYawyY67]DF6>;2 @    I N?3?3993310)! !#3 N y`HHj N@.  A3 YHI N?3?39/]]q]]q_q3933310!!!!!!d}i߰m L@-   A3 YH I N?3?39/]]q]]q_q3933310!!5!5!5!!mk{ff߰q8@ ? JO?3?39/]399333310!#"4!2&#"3275#5'Lu~KD; =7  N@-  A3 YH IN?3?39/]]q]]q_q399333310#!#3!3 ZJsT9 0@   I N?33?3393333310!57'5!9偁{97{{7n9 !@ @ I?]293210"'5326533M8E&K@[\J 6@     IN?3?3939333310!#373^X!A/wZ@5@ IN?2?993103!4@   IN?22?399933333310 ##!3!#47#f 3 4 _'iB&@  IN?3?399993310!##!3&53BA kx@/Bb,@   I N?3?3999933331033!#47#!heqZ  @  JO?3?3993310#"5432! !"Z   VXm"A@   #$!! I O?3?39/399933333310#"&547.=332=33254#"@P`]LCߺB\*+gS'hjjjk*@  NI?3?9/399333103254&++#! JV\g`TϙKI<@     N I?3?39/q3999333331032654&+#!2!HpafoD55IEH=={UC'L @ NI?33?9310#!5!!)%F @ I O?3?3993310#"&533265kjodoDz}hovm%"@  I N?3?33999910#.'#3>73673#ۅ'  њ! ))Zգg)9ǖfZ+Z1"3@ ""#$ NLO?3?3?9/3999333310'##"&546?54#"'6323265,8|ZvcJXa^mM]iE2u}t"w9Fi;>ZVEd!?@! "# /KLO?3?3?9/]39993333103>32327# 7>54#"'-;xYvdJW__kN\hG0t}u#v9F=@XUFhb.@   K NLO?2?3??999933310"&54632373#'#'26=4&#"P+MM\LP\JQԽqbeshk~ltvb='28c@7 $6( ,,59: ((/(((6/""L33O?333?2239/]]33/]3999333333102>32327#"'#"&=!.#"5>7>54&#"27!d5Hrvyd{HS2}Xh^FR[Y6.KWqLGIS=u}u;^7F\.,g[e= =@2&UDLX ,@  !"  F NLO?3?2??999933102#"&'##336"32654&XFo,% MRWGKVFPPջ/5V5d6sghzmwrsqhb0@   FNLO?2?3??9999333310"&546323&=3#'#'26754&#"P߬+MMXNP\JQԽqp,es`o~lwshVJ@+   / LO?3?39/]]]]q399333310"!4&"&54632!3267CU7P+ʷi^OEn5OUMWqο׼fZf7b`6@  L O?3?39/]]3933310267!2#"&=!.#"56E[V)Ϻmav=OUNVмֻg[e=8X%$Y@4! %&$$$$$$$/$$$ L O?3?39/]]_]]]q3993333310#"327#"&54675&54632.#"3{sbßy`gF5sKRP_i00V;5tqM\$aj:""&.&H"Y@4 !#$!!"""""""/""" LO?3?39/]]_]]]q39933333102654&#"'632#"'53254+5NoxLZAšdVֻjV".%'1:p]'WFo1;Z\f^` &4@  $'($%K!LOM?3?3?3?99933331026754&#"#"'532=7##"&54632373WLQYLʱPULap~lut-; csֻqb{ .@ P`p K N??]q2933310#"&546323#{y<=@9yi7226h5@    FK N?3??93933310?3 !#3faX` ZwG323>32#4#"j{TOު &GA Q{YKǨvb<5q5<Ǩyq^0@KN LM?2?3??99933310"'532654#"#33>32yL9'/.,]Uު )K^ 9< wb<5{h}  @  LO?3?399331032654&#"#"&54632LNZYOO[XN1ҹо;svvsttttػF @   LO?2?3993310"&'532654&#"'632JSl54jETcfWKe=j! $tswq-3h5}#@     L?3/]]q39910#54&#"#54632}O[XNо5ttttغh}5 #@     O?3/]]q399102673#"&'3XNѸNRspոps^0@   KM LO?2?3??999933310"&'##33632"3254&REl2 ޵ QQLMVI-7p^dsּ}cn}lss1fb.@   KO?3?33393331027#"&5#5?33#?LWuzk{@P#wXGXy)@  KN O?3??3993310'##"&5332653 (M݃_Re<73'!w3 )^8_&+ZOHf{&8@!'( G$O?3?393393333310&54632&#"#"&54'326[UXf<1ef|4We\JPZ1her''F*%I1Ao܅L}YIU_h^ #8@##  $%L ML" O?333?3??933333104&#">.54674632F?*.a|TQU?8daNqp7D|NɬndeQUathˮ^8@ !KML M?3?2??999993321023327#"&/#'.#"56`e(66)!)AMbp#Lma8"0$QRuV/# heRg6$ `{ ,@ _o R P??]q2933310432#"#3{yy{1iif`w!@  R PS?2??9993102&#"#33>X0 !jyި! /wf`tGISyiP?5adi P?5   Q?55fqR?5^w2@  0   SQ?3?3]q9993310%#"'##4632%"32654&^kX ӿLJ7_NEE5tDռ.fs;n{{kh S?55~R?5hs$+p@@" )),- (fY(i( ((((%_Y`Y ]Y?3++?+?39/_^]]]+_^]999333310 '# !3265!>32!3267"!.1irbe1+G0ebP_qr`j=&,销*.('}oq{'2p@$"11134!o %@H%%  (]Y .]Y ?+?+??999/+3/_^]]q33993332103632#"'##&#"#>35!3273#"'"3265 kp3K q#1 Jqkt^oBЏ{nEo 5\'4~@,6!22 & ++56$$$$o$$ $!$ @H ' '/]Y(]Y?+?+??999/+3/_^]]q3393333333103273#'#'##"323&=&#"#>32526754&#"qK p"; hl Jqumq{fqroZ2 (`nnGˈ!u+o@>#- * ,-    ` p    *!&]Y!*`Y*?3+3?+?9/3/_^]]q339333333323310!3273#"'!&#"#>35#5754632&#"! Jq%-q#Ϟ{N\NA:yo:4ѓRR/M? 57+-$$ ?"-(-  * 1;;]Y?3+3?33?999/_^]3/3/]33/9993333333332310&'!.#!#46733>323>32673!54&#"%54&#"ϧC yk)-nY-nJuxyQWyfPqQWdcL&e|MWNV$h/# yyc .-yyus'@2)&  () &_o @ H  #]Y?+?3?99/+_^]3/^]33999993333332310673!/!#46733>3254&#"Q uxD |h)3rV^gsFc}1))a~QSǤXyyns(4v@C 2-%2256 o  "")]Y"0]Y?+?+??999/3/_^]]q3393333333210"'#3273#"'!5&#"#>333632"324&p JqL q#+kiqhktemgl!Rws%j@@ ""&' o  @P` #dY ???+99/_^]3/^]]q33933332102&#"3273#"'!&#"#>333>>)%5JqL q#-4s /mm^s}w!]@8!! "#   o    @P` aY?+?9/_^]3/^]]q339933332103&#"#>325!2&#"3273#"'Js}vw#D=Jqmu!m s1W@1.30%0 23---% -+#`Y _Y?+?+9/_^]/933332310#"&'532654.#"#47&54632.#"673zKUQZL Db35#5?3!!3273#"'wPprJs#X9JoI#3mfm8A>^ y@F !"i`    & _ ^Y^Y?+9?+99/_^]3]/^]]33]933333310)5&#"#>327!5!3273#"'!%9qYWB!MwL\ X75'l's &N@'$$& & '(#!^Y!_Y&!!]Y!?+?+9/+99993333310"324&%4$!2&#"3632#"'#!xio{klu %RBVˤ D@&  *YH KN?3?39/]]]]q399333310#!#3!3C3L^!\@/     "#   bY   ^Y_Y?+?+99/+9339333333310!#"$5467'5%!5!32654&#"LزIXHwpovpuk|$peRZ~~v/f!4@Q+# !%% .( &  56& %, *" *'/ 11]Y1 !@$!$`Y! ]Y?+3?3?3+3?+9?3_^]99333333333333310)4&#"!327#"'#7&5#5?3!!!733632!X]q7 PprQ6uGX9'1G fyy##3Xf\\pgq^ J@+   Y"H|I ??9/]]+]3+3933323103#!#53!ѠϠ1)^W@2    qYg"H<L ]Y?+?9/_^]_]+]3+3993333210327#"&=#53!3#I#3y@s&~@I  $'( eY#w  "HL \   '    ]Y]Y?+?+_^]??9/_]]+]33+33999333333210"'#!#53336323#%27!"!.pϠ+kұb`\ ichc a;upqpqD^W@.   Y O  ]Y?+?39/_^]33+339333333210#"$'#53!!!325!11h^k@@|z/^$a@3 " ! %&" eY `Y^Y?+?3+3999/33+339333333210#! =#5367#5!!&'5!#3267!/\\2x2,t4{i}  DŽWU[Q;{~) -L@)++./  _Y!]Y (]Y ?+?+??/+99333310"'5326=#"'##!3632"32654&\G2033p31 k}qhkt^op)3Dq{EV!\) -U@-$+$$./ _Y(]Y _Y !]Y?+?+?+?/+99933333310"'5326=#'##"323&5!326754&#"]G4/33R; ho 2f*umo}fqr)3D23}bf!))u#W@-%!  ! $%_Y]Y `Y _Y ?+?+33?+/+993333333310"'5326=##5754632&#"!!3F]G2033Ϟ{N\NA:f)3DyRR/M323>323]G4/33QWpoQWuj)-nY-nf)3Dyyyy^MWNV)s"H@&   #$ _Y]Y _Y ?+?+??/+99333310"'5326=#4&#"!33>323]G2033V^r)3rf)3Dyy^QSs ,N@***-.  _Y!]Y (]Y ??+?+?/+993333310"'5326=#"'#!33632"324&\G2033p+k}qhkte)3Ds;JV!Rq)ws?@!   _YdY  _Y ?+??+/+9933310"'5326=#33>32&#"3\G2033-4h>)%5f)3D^^s \)s3K@)!1''145'.0  _Y%`Y _Y ?+?+/+993333310"'5326=#"&'53254.'.54632.#"5]G4/33@KzKUQ,lZy7ʿ\TLWz:T)3Dy ! (6`$-9&6\wWX$.I)<;5\xSX鱣#'L@'# %()# bY##_Y]Y]Y?+?+/+9/+9933333210"'5326=!#"'532654632&#"!]G2034屭r>=33:`L961=)3DB9;=>H)^=@   _Y _Y?+?3/+993332310!367!3!"'5326=!?$ (?]G4.34^yl`}3D )^O@)       _Y  _Y ?+??3/+999933333310"'5326=# ! !!3T]G4.34>{ZZw)3D;#d7)^F@%  _Y  ^Y  ^Y ?+9?+9/+9333310"'5326=!5!5!!]G4/33B )3DQV)ju&0w@B%2+ 00 12'gY?O "_Y `Y_Y -_Y ?+?+?+_^]/+9/_^]_]+9933333310"&=#'##"&546?54#"'63233273265>;M®eg3302Gvj)aK 1QeB5XZze\)s*S@,,) "" +,_Y&]Y_Y ^Y ?+?+?+?/+9993333310"&=#'##"3237!332726=4&#"R; hof33/4G}jo}fq)23B5!\N#(5W@.73 ", &&"67']Y0]Y)]Y ]Y ?+?+?+?+999333333310"323&=4632&#"327# 5467#'26754&#"o `L961=934=>}  hjumo}fqr23}b=>9BiL7f+!\)s&m@>(  $$'(  # fY#i# ####_Y   _Y_Y?+?+_^]/+9/_^]]]+_^]9333310 32!3267327#"&="!./eb33/4IfUaanr*3*.VB5{qq{N)s2@Q14+! %% + 34 ""{YkYtb<  ._Y`Y'_Y?+?+/+9/_^]_]]]q]qq+993333333310"&=# $54675&54632.#";#"!267327=T`瀐sX^wMqn gY33/4I) k 1э.&026B7AH}-)PB5N)#s4@P"## 3-- & 56"{YkYtb<  *0_Y`Y*`Y*?+?+/+9/_^]_]]]q]qq+993333333310"&532654&+532654&#"'>32#"'327fV`vpjzMPZw߉up@3302G)(.C>DA8=66&!-'9 "}efVwB5X)s")l@> +'&*+''fY  _Y `Y#_Y?+?+/+9/_^]_]]q3+39333331023327#"&5#"=!.#"5>267!!*33/4Gg_iUYu TosB5R 𔂒&2,$Rqzp{)L@)  _Y cY_Y?+??+_^]_]/+993333310"&=#!3327432#"R1f43.4GڦSS)^B5VGO?)s"9@!   #$_Y ]Y]Y?+?+/+99333310"&532654&#"'63 !"'327qF_rxdW*&33/4G)/2BLsB5)#!9@#  "#_Y ]Y ^Y?+?+/+93323310"&532654632&#"327ۋ=33:`L961=3302G)B9d=>uB5)^"H@&!$  #$ _Y_Y ]Y ?+?+?3/+99333310"&=#'##"&5!3265!3327#R)1s1V^r1f43.4G)NUsyyB5N)#^&i@7" & ""'(&&fY _Y^Y `Y ?+?+9/+9/_^]+9993333333310%!5!#"'327#"&532654&+?òp@3302GgV`}kVwB5(.C>C8\2@   K NLO?3?2??99993333102#"'##33>"326549K !oRVDK׷qcd4?+whvs^@  LO?2?39310 4632&#"327ö~r>nDrg0h4-C^h(E@" &&)*!#   L# O?3?39/399999333310632#"''67&54632.#""32654&5[f{S i)H|p=0R-^V\F)a1=*3'Ti\it7"S0ILm4oL@("%R;'X@2" () pGG%O?3??39/]3999999333310&'77#"&546327&''4&#"326q*?FbPCugjȮɵ13RElSJUIOOTI?#{/3`kG_CuPcm1J\bc_eqH#\@5 """$%""#######/### LO?3?39/]]_]]]q399333333102654&#"'>32#"'53254+5?isHT{y=_O^S̯dR!/%%1"o^'UFn1;Z\B1@ N GK?333?3?993333310###5754632&#"3;rrhX5O&Vef7>~!^6b.@    KM?2?9/33393332210"'5325#5333#1T5/3gqqnnbww5ˉh{^b- &6@  $'(#!%K!LOM?3?3?3?99933331026754&#"#"'532=7##"&54632373SGKTHrIQLal{msr-; csһqbhR-@   M KO?3?3?99933331047##"&5332653%mQ}WOh<\;8>vj \@7 _o  / KN??9/]]]]q333]q29333332103###533'432#"?ooooqssqD5hhf? @    KO?3?99310327#"&5^\;JPd{X#F  $@  K N?33?33993310'5!!57x{{@ $$ +, K N'L"M?3?333?3?999333310#4#"#33>323>32#"'53254#"BuQIѠ "vI=!uNxN1))VuSFævb98q7:xwvpb";@ " #$ KMO?333??339993333310#"'##"&533265332653#47HG;"xJuSFsSG sq7:>vo>yjB(MbV,@ KNL M?3?3??99933210#4&#"#"'5326533>32V32V)#)%%\}f]ZiBgX]bѧ=ҧ/G_~  ^^~ / ~^b,8@!'-.'%LO M?3?3?399333310#"'327#"53254&'.54632.#"4"!%""*G?1s>jzW@9e5\3))4ih @ MG?3?3932310#"'532654632&#"b{tS(%)#(zzD1$("*f~,(s )+1bHm <@  !"K OM?2?3?3333/9333310"'5326=#"&5#5?33#327E,""##{tes=3*;Jfb #/ZsXG-+zp#^@5        /   KNO?3??39/]]]3333399333333310'##"&=#533!33#%27! %Hjj#ooc;6E''ى)u=@    KO?3?333999333333102654&'5!##"&547#5![nKKsҷՍsnJfiY|-beYifN @   K O?2?3993310"&5332653쯲IODCӴVdXXd^j'@ LK O?3??39933310#"&53326=4&#"5632jOWJL'#!+2SpsVdXXd(.~z @    N K??393310 #&'##$ۓ%]A>`JR 0@ KN?3?39999333310!5!5!!d>f}柉)Rb;5@    K NM?2?39?399333310"&=!5!5!!327XiPd>f%#$.bgtw}柉)/# R9VK@%   ! K N?3339?399/3933333310'67!5!5!3>32#7254#"( odDV@yWM]y1&4`'.&}|c]Ong=4=4-h6@  MK?39?9/3393333310!5!#"'532654&+kPȬDAktR (Ԟ8""[\ZX^F T@3Zy/ G O?3?39/]]]]]]qq399333310#"32267!"!.FPJIROG:I_!^ @ /29/310432#"&%432#"&#&'5!^9JJ9;F>>EK87!#59JJ9;F9JJ954.54>54#"'632Z!(!!(!#+#2,.C6h & $$ZN?  7=   u%@_ o   _/]3]210"#".=332676;Nwp:iu8 +.IK5&-&;w[1;46?@o/]210!7!#V/@o/]310!%7!/V#ŝ?@ _/]2310!'!L"V/@ _/]3310!'%!/V"L99+@_o/_/]2/]3310%7%'V1V}}9+@_o/_/]3/]3310'%7V1V1}}J  H/+2?9102&#"#3>h'%%>4:B LTwE#,TR @/?/_/]]10&'5673_x-uHmgiG:,g#@  0O_/]]2910#.'537673%#567&'5 NRh*=*#hd/_'nO=[T2:&A;%+55+55\&V D?9%+55^Rf&6'ORd /&15%(,%+5+5+5\R&V'Odm/3%&*%+5+5)yf&7OR@  %&+5+5/7 &WOb@  %+5]q5)Ry&7d  %+5/R7L&Wd} %+5)y&7M@Pp %+5]5/EL&WM@ Pp%+5]5)gy&7K1@  @ H @ P p  %+5]+q5/gL&WKz.@@ H@Pp3# %+5]+q5r^&8jz!@ P% %+55]55r^&Xj1z!@ P' %+55]55Y^&8R-H@ HP# %+5]++5Y^&XR/0H@ HP% %+5]++5g^&8K.@@ H@Pp %+5]+q5g^&XK1.@@ H@Pp" %+5]+q5^^&8 HR@ %&%1 %+55+55 &X H '3 %+55^7&8 ER!@& %+555+q555&X E %+5553`&9R/R@ &%+5+5&YR  %+5R3&9d  %+5R^&Yd   %+5f&:OR@ "%%&+5+5&ZO1 %+5R&:d^" %+5R^&Zd %+5Vf&;OqR& %+5+5 &[O   %+5VV&;j=R@ !& %+55+55 &[j   %+55f&<OFR@ & %+5+5&\O  %+51qs&=KR@ & %+5+57!&]K  %+51Rq&=d  %+57R^&]du   %+51q&=M@ P p    %+5]57^&]M@ P p    %+5]5&KM7@Pp %+5]5/7&Wj$ߴ( %+55&ZP "%+55&\P  %+55V;u&D U.*%+5?&AO{@ &  %+5+5#R@+## $%lYiYkY?+?+?9/+399933333103!2!"'32654!#57.#"?1(㴺ݜPNX"`%"թK0,mjE<\X&~s  +1%+5\X&~?Ӵ5+%+5\5&~/4+%+55\5&~/4:%+55\5&~` -4/%+55\5&~L 4>%+55\&~#CO%+55\&~CO%+55&$pt%+5?5&$ct%+5?5'$3@ I%+55?55'$3@ I%+55?55'$3@ K%+55?55'$3^ %+55?55{|'$!@)))?))22%+55]q55{|'$!@)))?))22%+55]q55N%X&N '-%+5N%X&31'%+5N%5&  0'%+55N%5&06%+55N%5&1 10*%+55N%5&  09%+55'(pt%+5?5'(ctv %+5?5+'() %+55?55+'()%+55?55'(ȴ%+55?55'(ȴ%+55?55X& ( %+5X&j %+55&B( %+555&B, %+555&s ( %+555&^ ( %+55&F -9 %+55&1-9 %+559'+pt%+5?59'+ctv %+5?5'+) %+55?55'+)%+55?55f'+ȴ%+55?55f'+ȴ%+55?55^|'+$@)))?))00%+55]q55^|'+$@)))?))00%+55]q55X&3  %+5X& %+55& ! %+555& %+55,5& 3! %+555& ! %+55&  %+55& %+55',-pt%+5?5',!ct %+5?59',^޴%+55?559',^޴##%+55?55N',s˴%+55?55b',̴%+55?55)|',N!@)))?))00%+55]q55)|',N!@)))?))00%+55]q55\X&Ru $  %+5\X&R?$! %+5\5&R+ -" %+55\5&R+ #1 %+55\5&RR '- %+55\5&R= #- %+55v'2pt@  %+5?5'2ct#%+5?5'2@ "%+55?55'2@ "%%%+55?55'2"%+55?55'2@ "`((%+55?55X&  %+5X&Pд %+55&D)%+555&D-%+555&u )%+555&` )%+55&H .:%+55&3.:%+55L'<Nct %+5?5'<%+55?55'<%+55?55|'<!@)))?))--%+55]q55m{X&o 2. %%+5m{X&92/ %%+5m{5&% ;0 %%+55m{5&1? %%+55m{5&` ;;, %%+55m{5&L 21; %%+55m{&) @L %%+55m{&@L %%+55'vpt$'' %+5?5'vct.ݴ(( %+5?59'v'-!! %+55?559'v'-00 %+55?55'v-w(( %+55?55'v-|77 %+55?55|'vs$@)))?))ʹ'' %+55]q55|'vs$@)))?))Ǵ"" %+55]q55\!&~!/+%+5\!&~Z J3/%+5N%!&ƴ+'%+5N%!&1 T/+%+5!&/ %+5!&h > %+5;!&  %+5!&ڴ %+5\!&R" %+5\!&R= =" %+5!&'%+5!&` 4%+5m{!& )(%+5m{!&7մ0/%+5\X&~'s9@ GA"% +1%+5+5\X&~'?9FB"%Ӵ5+%+5+5\5&~&/9NJ"%=+%+55+5\5&~&/9NJ"%4:%+55+5\5&~&`9@ OI"%%=.%+55+5\5&~&L9@ OI!%4>%+55+5\&~&#9^X"%CO%+55+5\&~&9^X"%CO%+55+5&$'pt %+-%+5+5?5'ct&$! %+-%+5+55?5 ''$3!@  %3&5%+5+55?55 ''$3!@  %3&5%+5+55?55 ''$3!@  %3&5%+5+55?55 ''$3!@  %3&5%+5+55?55 |''${,@###?##<,,$$%B5.D%+5+55]q55 |''${,@###?##<,,$$%B5.D%+5+55]q55X&'@ 1% %0 %+5+5X&'j޵1% % %+5+55&&B޶9- % %+55+55&&B޶9- %$ %+55+55&&s@ 9- %& %+55+55&&^@ 9- %' %+55+5&&F@ H< %-9 %+55+5&&1޶H< %-9 %+55+5 '+'pt%)+%+5+5?5 '+'ctv %)+%+5+5?5 _'+)'H# %1$ 3%+5+55?55 _'+)'H###%1$ 3%+5+55?55 6'+'#ȵ%1$ 3%+5+55?55 6'+'#ȵ%1$ 3%+5+55?55 .|'+'/@###?##00%@3 B%+5+55]q55 .|'+'/@###?##00%@3 B%+5+55]q55m{X&'oT@ D8%(.%+5+5m{X&'9TD8%2(%+5+5m{5&'%T@ L@%1( %%+55+5m{5&'TL@%17 %%+55+5m{5&'`T@ L@%C1, %%+55+5m{5&'LT@ L@%21; %%+55+5m{&')T@ [O%@L %%+55+5m{&'T[O%@L %%+55+5 'v'pt$'' %δ>1@%+5+5?5 %'ct'v@ 1%ʹ>1$@%+5+5?5 ''v'q@  %%%δF9,H%+5+5?55 ''v'q@  %%%δF9,H%+5+5?55 +''v@  %%%ʹF9,H%+5+5?55 @''v)@  %%%δF9,H%+5+5?55 |''vs*@###?##344%ʹUH;W%+5+5]q55 |''vs*@###?##944%ʹUH;W%+5+5]q55\+&~N)  1+%+5\&~M)  +,%+5\!&~&!9?;"%/3%+5+5\q&~972"%+5\!&~&Z9@ ?;"%J3/%+5+5\&~R/;%+5\&~&R9NI"%/;%+5+5}&$NVR@ %&+5+5&$MXR@ %&+5+5&$x@ I%+5?5&$$I%+5?5&$%+5X&@  @ _  /]]2931046325>5.A1AMBF5D5:WIqV1 = (@    Y ?+/_^]93310327#"=#+*"=_jg31 ޤW R /O@1 - !01,$$$@ H$)!$o _  /]3333/]3/+]33933104632#"&%4632#"&7".#"#>3232673F;9JJ9;FF;9JJ9;FG-OG?,( } u^1QG=*) }rF?>>?>? %+5+5&R3% %+5&&R3޵9- %% %+5+5'(Y %+5?5'(%+5?5='+Y %+5?51'+%+5?5 6&+ %+550@  _o_/]]29310#.'5!%46325>5&aV+$50@  _o_/]]2931067!#%46325>5&17 2@4AGu9@jB802Q>aV+$&R@7 $ '(#@ H  o / _   /]]22/3/+]3393104632565.%".#"#>3232673:3>?qq29-OG@+) } u_1QG>*) }r)1H3ZeP50!*.l!-+tw+&N  %+5&M  %+59&@ ' %+5559&@ ' %+555&R  %+5&@  %+555}&,N$R@ &  %+5+5?&,M$R@ & %+5+5', Y%+5?5',˴%+5?55.@   _o_/]]29310.54632#.'5! j@9vGA4@Q2G<5.@   _o_/]]29310.5463267!# j@9vGA4@:7 u;`$+V`>Q2壘;E&P@5 $ '(#@ H o   /_/]]22/3/+]339310.546327".#"#>323267392qq?>3:#-OG@+) } u_1QG>*) }r&05PeZ3H1B!*.l!-+tw+&N'%+5&M'%+59&+/%+5559&+/%+555yX&{  )% %+5yX&H)& %+5&R5&%+5&?7C%+555}&<NR@  & %+5+5&<MR@  & %+5+5;'<=Y%+5?5;'<=@ %+5?5}'3ct!v%+5?596@    P/]q223933310#.'53%432#"&%432#"&2u ?ʁ9JJ9:GR9JJ9@" #$ `p!?3?39/]39993333104632&#"3632#"&2654&#"3C<.6G~zT5B8;8EBpb"FA7B@+AT+9"6@  #$ !?3?39/]3999333310#"'53267##"&54632%"32654&I613G~z5B8;7FD3pb#GA7A?+CSZS1z S?55hSVx  S?55hU}z S?55'`wj /@     R P?3?3999333310%373 # #9|r bS`x S?55+d@P YZ Y YY?+?+9/+9/_^]_]]q]]+_^]33933333310#"32&#"!!!!!! 㲒ZvYg]V)CD9ߐ{J%+u@F& ( "##"  )( ,- ()#)%" "kY   %kY/3/]3+/3/3+9933333333310'67#7&'#7&5%7373&#9obBx!!NB%/- !KF!7W>=DdkH-9A Q<g# sPRf0Jh%K@&"&' kY  kY iY?+?+9/+999333310"33>32&#"67# 4$32.ӣѼ# #gQ.!ybŚ$dl}VJZ 'KzmZi6*BT(W@.! !!)*!%  ]Y?33/+3?33?99333333310)5#54&#"!33>323632!4&#"ϚfQWuj)-nasGKQWpohlyy^MWqR'yy#&*@m $# !)'') &% +, *pY % "pY//$'?3?39/]q]+9_^]]+9933333333333333103!333#3#!###535#3'#35#3&'#wBuuuuwww[/TdT ) )A;@F/* 5*$$* <=*5$--3_Y- iY   iY "_Y?+?+?39/_^]+9?+993333333331032654&+!!23!#"&'53254&'.54632.#"Hj]chD_gAE?FzfĮJBu32"32654& #!!32654&#"'>\yEjO,ѺFW &gKa@CR'zTO\Ksre)4n%ε cnANsZEN~^$$'3q",[@/ '#-.*   %lY  lY#?+?+?/9/999993333333210#"'532654&' #7.546324#">faxķHH0?2=6Kܨj=}S̷^\8,(.T{m鱴Ad\oYAMMOE4 <: {Y:!@Q   pY nY/_0`p  pY?+3?9/_^]q]q+99/3+39333333310!.+5!!3#!53267!z]H&{mqhVaNiA_W; dD"2Y@4# ++ 34       p  /'?3?39/]39/]9/3933333103254&+#!2#%4$32#"$732$54$#"吪SY/^^m+*լ֭ۢQIE^ZƬ֭+* +15@M ,1 .44&267& 11.0@#?O 54 ?3???99//]3]399/399333333333310'##3#"'532654&'.54632&#"/ #21#f=h86>A3[M-t3N%'ADuP78L+@ir1 %9L5`q1+!,^ =J=J^ <@!  `Y `Y?+?9/_^]_]+93310!!5!!5!1M^ :'&{u?5&t'!uB$?5?sCd^D 1@  p /3/]/93310#&'5673!9>HH>9)DH$HDV @   //293105673&'#DH$HDV:=HH=:#d^D 1@    p     /3//]93310&'3#67!59>HH>9#DH$HDV @    //29310%67#&'53+DH$HDV9>HH>9d^D?@%  p /3/3/]39333310#&'5673!&'3#679>HH>99>HH>9)DH$HDDH$HD(@   /2/29333105673&'67#&'5DH$HDDH$HD:=HH=:9>HH>9H0@   /2/2293333310!!5673&'67#&'5 DH$HDDH$HDhPX:=HH=:9>HH>9wu)}y`@ //3993103!!^j8^@   /3/29933104>32#4&#"rуwfŠdHP @@&  P_ / ? o  /]3/]3/]3993333105!5!5!d8d7 @  /3/29933103 %! {RVX9?@ /2/99310!!#X?#@  /3/99310#4632#"'&'&#"}?L3% &!" @/)3 )''#i@  //3993103#"&546323265#9P3## #>/'5)%37/333105! h//93103#בK7@ /2/93310!!#'k7n7@ /3/932105!# )@ //3933103!!n@ //3932105!3  @   ///39333103!!#knn@  ///39332105!3# K7@   /32/9323105!!# kn@   //339323105!3! n (@    ///332933323105!3!!# knn6@ _/]]3_]q/_]33333105!5! BZ@  /2/39933103#3#ّiK K >@!  _ /]]2_]q//_]39333310!!!!#'kkב"7 &@   /33/39933310!###ؑ7nn# B@#   _ /]]2_]q/3/_]399333310!!#!!#iro" :@ _/]]3_]q//_]393323105!5!5!# i)ג(7 "@ /32/399332105!### ݑؑn @@"  _  /]]3_]q/3/_]399332310#!5#!5!ӑtt(F(ޑ <@    _//]3/]]3_]q93333103!!!!k#ב $@   /3/3399333103!!33B%n#n @@"      _/2/]3/]]3_]q993333103!!3!!ّJ%i# 8@  _//]3/]]3_]q93323105!5!5!3 iג) "@ /3/339933210!5!333#ؑn >@!        _/3/]3/]]3_]q99332310!5!3!3!5!#LF B@#  _ ///]]3_]q/_]3933333103!!!!#kk#ב" *@    /3/3/3993333103!!#3#Bnn K L@(   _    /3/3/]]3_]q/_]39933333310#3!!#3!!jr " # >@!  _ ///]]3_]q/_]3933323105!5!5!3# iגK &@   /3/3/3993332105!3#3# 㑑iK#K J@'    _ /3/3/]]3_]q/_]399333323103#3!5!#!5!B㑑tK (ޑ B@#   _   /]]3_]q//_]32932333105!!#5! ki"h7 (@    /322/3993323105!!### ؑnn N@)    _ /]]3_]q/3/_]3339933233310#!5!3!!#!5jtrrBޑ"ؒ @@"  _  //]3/]]33_]q932333105!3!5! BZ# (@   /3/333993323105!333! ؑnn L@(         _  /3/]3/]]33_]q399332333103!!3!5!5!B#oV@-   _  ///]]33_]q3/_]3329333332333105!5!5!3!!!!# ikkג#ב">@      /3/3/333339933333323103!!###!5!33Bؑnnnn d@4  _  /3/3/]]33_]q3/_]333993333332333103!!#!5!3!!#3!5!Bؑtr#ޑ" //3310!!V//3310!!V//3310!!V //9210!!+ //9310!!+ *fw% #'+/37;?CGKOSW[_cgkosw{@"2Jjj#3Kk.FVznn/GW{o6Nff7Og*BZ~rr+C[s :Rbb ;Sc&>^vv'?_wwcsgokcgkk`dh_[WW\XTOSKKLPHC?GG@n?o*Z+[BrCs.^/_FvGwA#&.6>JFF'/7?KG"*2:NBB#+3;OCCG@ PQӸCи@ԯ?<;87{{|4xgkosw3ccdhlpt0`OSW[_/KKLPTX\,H7;?CG+3348<@D(0#'+/' $(,$ #  KH@Ԩx`H00H`x DAGO   L/333/3339//////////33333333333333333333333333333393333333333333333333333333333333333333332333103#73#73#73#73#73#3#73#73#73#73#73#3#73#73#73#73#73#3#73#73#73#73#73#3#73#73#73#73#73#3#%3#73#73#73#%3#3#'3#'3#'3#'3#'3#3#73#73#73#73#73#3#'3#'3#'3#'3#'3#3#73#73#73#73#73#3#73#73#73#73#73#3#73#73#73#73#73#3#3#3#3#3#3#3#3#3#3#3#3#fiiiiiihhffffffffffhhiiiiZiiiiiihhffffffffffhhiiiiZiiiiiihhffffffffhhiiiiffffffhhiiiiiifffffffhhiiiiiffffhhiiiiiifffffffhhiiiiffffffhhiiiiZiiiiiihhffffffiiiiffiiiiffiiiiffiiiiffiiiiiiffbbbbbbbbbbbc^^^^^^^^^^^````````````e^^^^^^^^^^^`aaaaaaaaaaad^^^^^^^^^^^`cccccccccccb\\\\\\\\\\\bccccccccccc^```````````bbbbbbbbbbb%```````````bc^``e^`ad^`cb\bc^`b%`C%IMQUY]aeimquy}  !%)-159=AEIMQAS@zKk h| OoLldi}SsPp`"eWwTt\&a# +P;;Xxؿ)H*99]'A!/L?? ,Q<%D.55 &I+648<@DHH0M@26:>BFFA "E/22@6<@ ؾ RS@  $(,0ֹ:>Gʽɹ59ȹ48+/D*.C%)$( !@ ?| {~ osw <knrv ;jj\`dh[_cg@OSW8KNRV7JJDHCGLP@4 kKKk  ׹;?HKO@ 3"&*./333/339//////////333333333333333333333333333333293333333333333333333333333333333333333332333310!35#35#35#35#35#353353353353353353353#3#3#3#3#3#335335335335#3'#3'#3'#335335335335#373533533535!355#%355##5##5##5#353353353355##5##5##5#35335335335#3'#3'#3'#3#3'#3'#3'#335335#3'#335335#3735355#5##5#353355##5#35335#3'#3#3'#3+jjjjjjjjjjjkjkjkjmkjkjjkkkkkkkkkkkkkkjkjkjmkkkjjjjjjkjkjkjmjjkjkjmkk?kkmkkmjkjkjkkjkjkjmkkmjkjkjkkjkjkjmkkkjjjjjjmmkkkkkkjkjjjjkkjkjjkkjjWjjjjkjjkjjjjkjjkjjjjkkjjjjj!c c"a c!b!`````````````b^^^\`h^^^^^^^^cccccccb^^^^^^^^aaaaaaaa^^^^^^^^^^ccccccccb\\\\\\\\cccccccc^````````bbbbbbb bbbbbbb^^^^cccb^^^^aaaa^^^^^ccccb\\\\cccc^````bbb bbb{Z//9910!!{!!@  /2/3993310!!!7L17}1mh{//9910!!hmh{@  /3/3993310!!!hKPb//3310!!L//9910! XVRZ//910 7L//9910 LRZ//9910Z79e-)@  ! /3/39933104>32#".732>54.#"wx{yy{xwV`bcb`c``dyyyyxyy{b``bcbbbV^R'/7?GOW_gow@X\PhhTl8xx<|(pp,t ``$dHH L@@D0044DLdt|l\ JrvNvvvBz~F~~~2jn6nnZ^^RVVVVV:>>> *..v~n^V>..>V^n~v&f0b@bb"0p&/&?&&&/]]/]9///////32]32]3232q32]32]3293333333333333333333333310#"5432'#"5432#"5432#"5432#"5432#"5432#"5432#"5432#"5432#"5432#"5432#"5432#"5432%#"5432#"5432'#"5432377349947575#3773865567557R75577667377349944976#58856556\677675577667667+557775555885Z557w55763:C558337775555776557737+558#  //99102#"54>jmsoujlw)@  //9933103!32>54.#")wvuwwwvu}Bwwwutww)#'@ $%  //933103!4>32#".'32>54.#")R`babbab`Nwvuwwwvu}B`bb`c``cwwwutwwsbu &@   /33/]3993310#"&546324&#"326bcfdiFIKgFEgcIN_}khfJHfFffFHdhy $0:k@%+ 6+:;<51@) H168833@ H(.""O"_"3"3"  /  /]3/399//]333+3]+29333310#"'4! 4#"32#"&54632#"&54632327#"'ybbZٗ31Z-!!--!!-+!!//!!+LL=`bHgj34V// -- // --# #-S@4( $./)--!O_-&+++@ H++  /  /]/99//+]]]32]3910#"'4! 4&#"326%4&#"326327'#"'bc0!--!0.!//!.bb>KLHgj{ -- // -- //ۺ#Fs;)5p@=3$-%-"') 3 3 67"   $'0*()/3/39/3933333333333333310373#'#5&''7&'#5367'767"32654&BAe;-VL12WXByd+N P)opÉ;'--qt>}`+%* J-d}>^1N =LJŇP'$T@+  ""%& /@/3/]99//]333339333333310.54632!!#!5!"327654&qqwTVhL%Xw{TV;>wBh}VTylFFxUVy>=TVwR,8F@#0',!66,'9:,*3$-$*/3/399/99933333310&'&54763327632".'#"&54632"32654&+ !C=#"&5467>!aFXdP{XZ[Xe`Ga^%%`]ZRw;3C@&'. 45*   .#  //99//]99233]3910)7>5'#"&54672&'&5463267632#".'Fw^69Zs\=e% qtET'iCJt8v_=1op#8wL/yuzs3B'$'ykVb'NKuu2Qi}x6fZy@   /3/99910./.54632>32bZ[K6dV'!XaXoV{eAkswwucVB   //9910&'6J{FT+t}FiRmX;.@  //9/93333103#654&'#"&54632Ll^/9r@k99}M+/dyyw {7-NsB@#      /3/933/9333310#"54632#"&54632%%5_s{N/+ىs9:wJ6.'DeQovt5-Luguf7u@E    !       `//]q/9///99933333333333310##57573%377```J`X=@`^``F\^` Z ?v@A   hY hY   iY?+?9/_^]3+3_^]]2+_^]3933333323103#535#53!!!!!!6==Qǰqo@>   hY    hY`  ??9/]]]]3+3_^]]2+39333332333103#3#!#535#53!ѠϠ1㬛𬛬1?[@6      o    ? iY?+?9/_^]3/^]]q339933332103&#"#>3!3273#"'!L r#6Jo(mPPm~@I  qY $H    iY 0p o  iY ?+_^]?9/_]_]+9/_^]+3+399333333310!#!#53! 3#32654&+ʤ Dfwn{qlmhH W@."  !"iY  iY  kY #?+?+?9/_^]+99933333310327# ! !'32654&+<0>3_4*d^1R?< i9݁91bihXVV;!&+@O ""$%*+!!)%$,- ")+$%+  +gY+++  `Y _Y ?+?+_^]??9/]+93999?93333333333310#'##.546?'6;>54'7`;32&#"V?! ))p,c'9J'^h}j{v ]lV'*@ (!)   #iY?+?3?393310)&'!!>7!67>32&#"H 50 11+%$, $yJI$!*-(),63ݢ9B3aK0'\Js$+@%&  aY?3?3?+99310! # !!36?!36>32&#"7Vt C0'Pn%|UA#?D^XLUM4|̚ W`Ds$U@-&  %& " hY "rY ??+?9/+999999333310!#527.54632367! 654&#"VwX6zy+*'?VZDF'&S_-{stfdmrs}h:Y3Z,./1^@:  iYF!L;??9/]]]]]_]q_q]q+_^]993310!!!!16Cw{^D@* `Y$ Hv$ I??9/]+]q]++993310!!!V^R3^\u ;@   !_Y ]Y ?+3?+?93333104&#"> 474632^Z9@?owZJֺpNOa <*zw4!,@ _o/]/]99//993310'%'JII)IImmml-@ 0 _o0/]]3/]]10##"&54632PF;9JJ9;F[?==?>?>?>?>?32uxJhg#96+ )@ fv P  /]33]/].2103273#"%ϧW,'l3 $@ /3/99993310!#!5!3d+\+ $@ /3/99993310!#!5!3d+%F $@ /3/99993310!#!5!3n!ZZ @  /3/999310!#!5!3n!DN @ /3/999310!# 7 3g\=H`3R "@ /3/9/3993310!#!7!3bH3o`RN @  /3/99993310!#73^J^sN @  /3/99993310!#5 73gRۇjh0hF@  /3/999310!# 73qZyfkFq @  /3/99993310!#73q_ZGd)5 @ /3/999310!# 7 3RkGHyN!5 "@ /3/9993310!# 7 3Rk`/L-!P "@ /3/9/3993310!#!7!3ysdH^- @  /3/99993310!# 73`wcFFH@ /3/999310!#73vq=Df-q @  /3/99993310!#73qFsGVH!% @ /3/999310!# 7 3>{GHZ1#% #@ /3/9993310!# 7 533X3'5g% #@ /3/9993310!# 7 3D{rVJ1}q' "@ /3/9/3993310!#!7!3by R1X/@  /3/999310!# 73HՇH7%q @  /3/99993310!#573q>{G\1# @  /3/39999310!# 7 36}MH)R/) $@ /3/39993310!# 7 530XAuP/j5 $@ /3/39993310!# 7 3NN-qT+o5 $@ /3/39993310!# 7%3Nu7T+}/@  /3/399310)733+NT-)q@ /3/999310!#73qB=T-)P@  /3/999310!#!'!`sboL #@ /3/9993310!# ' 3\H6fy3L #@ /3/9993310!# ' 3VH)hy?L #@ /3/9993310!#5' 3THhy-^ @ /3/999310!#' 3P5fy=Lq@ //9999310!#'3q^hy"@ //9/3999310!#!5!3qT; &@ //9/399993310!#!5!3`/h{T &@ //9/399993310!#!5!35%"@ //9/3999310!#!5!3@P@ //999310!# 7 3i``ybVL "@ //9993310!# 7 3e`;H`FF $@ //9/39993310!#!7!3gb+\t]^L @ //9993310!#73^'ezL@  //9999310!# 73e\هseRdZLq @ //9993310!#73qe^=ddZ/@ //999310!# 7 3Hu7T`H?9 "@ //9993310!# 7 53Ru9HpHF? "@ //9993310!# 7 3Mw\sX=T9H? $@ //9/39993310!#!7!3lwo V=1?@  //9999310!# 73\w߇5:=?q @ //9993310!#73qXw1-B=+5 @ //3999310!# 7 3N}5H)1q5 #@ //39993310!# 7 53N}<Au1]j5 #@ //39993310!# 7 3NN-q -+o5 #@ //39993310!# 7%3Nu7 -5@  //3999310)7331N߇ -P5q@ //9999310!#73qN3 -yL@  /3/999310!#!'!nwJ{L #@ /3/9993310!# ' 3nH J{3L #@ /3/9993310!# ' 3nH)T?J{?L #@ /3/9993310!#5 ' 3nHu^J{-L @ /3/999310!# ' 3n5RjJ{=hq@ //9999310!#'3qo;L{L@ //9999310!#'3kNf{F $@ //9/39993310!#!'!3bj\L "@ //9993310!# ' 3\H5gyFL "@ //9993310!# ' 3VHiyPL@ //999310!#' 3ifrq\%Lq @ //9993310!#'53q^g"@ //9/3999310!#!5!3XV9ZB^ &@ //9/399993310!#!5!3cf)9% &@ //9/399993310!#!5!3b-%w"@ //9/3999310!#!5!3ZV@ //999310!# 73f^ q%^`V "@ //9993310!# 7 53o^h^xX "@ //9993310!# 7 3q\3Hmg1ZV $@ //9/39993310!#!7!3bL+Vm\V@ //9999310!#73'^{^\q @ //9993310!#73qu\/3g7 @ //3999310!# 7 3=q+\=LD7 #@ //39993310!# 7 53Po+^-L i7 #@ //39993310!# 7 3Po?J?LL)7 #@ //39993310!# 7 3PqX/XLBb7@  //3999310)7331PqLb7q@ //9999310!#73qPq?L{H@  /3/999310!##'!y\1F #@ /3/9993310!# ' 3{Ny1PF #@ /3/9993310!# ' 3{Hb1F #@ /3/9993310!#5 ' 3{HtD1\F @ /3/999310!# ' 3{HX1)Fq@ //9999310!#'3q{91@  //9999310!#' 3wbL^=5 $@ //9/39993310!##'!3ws;s=9 "@ //9993310!# ' 3uHXqHETJ9 "@ //9993310!#5 ' 3uHHG}9@ //999310!# ' 3uHHG9q @ //9993310!#'53qw>K@  //9999310!#' 3[VHZdbVs @ //9993310 '53#/[{b $@ //9/39993310!#!'!3[HVbk^ "@ //9993310!# ' 3[VHB1by@ //999310!#' 3_VHLdy}Lq @ //9993310!#'3q^d+"@ //9/3999310!#!5!3LR= &@ //9/399993310!#!5!3aNA%1o5 &@ //9/399993310!#!5!3qÇ"@ //9/3999310!5!3#d+VL @ //3999310!# 73e\-yfL #@ //39993310!# 753e\ }VyfL #@ //39993310!# 7 3e\j?yf)L #@ //39993310!# 7 3e\=J3yf6P@  //3999310)7!31i\y whPq@ //9999310!#73qi\;wh/@  /3/399310!##'!l-T5 $@ /3/39993310!#%' 3H{-T75 $@ /3/39993310!# ' 3HJ-T+ $@ /3/39993310!#5 ' 3H/P% @  /3/39999310!# ' 3}H)/R))q@ //3999310!#'3qÁ)-T/@  //3999310!#' 3TH7H' "@ //39/3993310!##'!3eyT19% #@ //39993310!# ' 3{Nq}1JV% #@ //39993310!#5 ' 33h5@% @ //3999310!# ' 3{H#1Z%q @  //399993310!#'53q{Šy1H@ //3999310!#'3vfD=- @  //399993310!#' 3mwbFFcP "@ //39/3993310!#!'!3sXdH^5 #@ //39993310!# ' 3kL!-L5 @ //3999310!# ' 3kL!Ny-q @  //399993310!#'3qs!HVF@  //3999310!#' 3RZZjfyN @  //399993310!#' 53LRHh0hjN @  //399993310!#'3}^s^JR "@ //39/3993310!#!'!3bqlV`sN @ //3999310!# ' 3\H3`Fq @  //399993310!#'3qZ)d @  //3999310!#!5!3D $@ //399993310!#!5!53'ه) $@ //399993310!#!5!3sD $@ //399993310!#!5!33\+Շ\\&~ ?@  .-%+555\&~ @@  .-%+555\&~ A@  .-%+555\&~ B@  FE%+555\?&~ W@  -5%+555\?&~ V@  .6%+555\?&~ U@  .6%+555\?&~ T@  .6%+555& ?@  %+555& @@  %+555& A@  %+555& B@ )( %+555?& W@  %+555?& V@  %+555?& U@  %+555?& T@  %+555& ?%+555& @@ %+555& A%+555& B1)%+555?& W@  %+555?& V@  (%+555?& U@ !%+555?& T@  7%+555& S@  %+5555& R@  %+5555& Q@ 4. %+5555& P@ 4. %+5555& S%+5555& R%+5555& Q<6%+5555& P<6%+5555Rh:@  iYiY"?+?+??999333310"'32654&#"!33>32iNPBfX}1DR>fmyR ^#U@/""$% ## ## iYiY?+?+?9/_^]9/^]993331032654&#"!33>32# =㍘}1D1a9fm!)&_@4&  &'( ^YE *    #^Y#^Y#?+?+9/_^]_]]+9933333103254&+532654&#"%4$32! $5ꑊVDszpZ wpe_]1ιѲF l@J    @ H(:O//@H@H/++]qr^]22^]/+33//^]29310!!%#.'5!%46325>5&FZ_V,#F  l@J   @ H ( :O//@H@H/++]qr^]22^]/+33//^]29310!!67!#%46325>5&FZh6 2@4AGy9@jhB802Q>_V,#Fl@J    @ H(:O//@H@H/++]qr^]22^]/+33//^]29310!!.54632#.'5!FZj?9zFA5@Q2G<F l@J   @ H(:O//@H@H/++]qr^]33^]/+33//^]29310.5463267!#!!sk@9zFA5@96 u;Za#,V^>Q2;E>! @   _  /]2104632#"&5>7!F;9JJ9;FEkH@Es?>>?>?<>> PieT6xT/@ /  yXh /]22]]q/]33310!!4632#"&%4632#"&ZF;9JJ9;FF;9JJ9;F?>>?<>>>?<>>d /=@* @H , $/$?$$))!)$_/]3]/]3]/+3104632#"&%4632#"&".#"#>3232673F;9JJ9;FF;9JJ9;FE+ME=*& } o]0OD<)& } oh?>>?<>>>?<>>!*.k!-,rzh?G,d@d  W@@+ H/? _  /]3]/]]3]/+]]q10567!".#"#>3232673fVLAHp+ME=*& } o]0OD<)& } orA1!*.k!-,rzT 3@!O y X h    /]33]]q/]]]10.'5!!!I/L}2Z2026KT 3@!O y X h    /]33]]q/]]]105>7!!!>sL1TZF/1;Ku &?@)`### #0### _  /]3333/]]]qr29104632#"&%4632#"&3673!.'F;9JJ9;FF;9JJ9;FCUNQ0<F?>>?>?>?>?3232673!!+ME=*& } o]0OD<)& } oZ!)/k!,,rzT-@hxO?O _  /]33/]q2]10!!4632#"&ZF;9JJ9;F׾?>>?>?>?>?>?>?>?>?>?Q2壘CBJ? &`@A !'("@ H //_/]r22/]q33/+293310"&'332673.54632#.'5!XXYZj@9wFA4@5y 113229`#,V_>Q2?@(RJ? %d@C $ $ &'$ @ H //_/]r22/]q33/+2933310"&'33267367!#%46325>5&XXYZ7 1@5AFw9@k1322XA502Q>`V,#9? $^@A# #%&#@ H //_/]r22/]q33/+29310 332673#.'5!%46325>5&#XXYZ5y 7A4AFw9@k 1313??@02Q>`V,##K@'iY iY ?+?+?3?9999333310) ! # #"'5326! !#>_T@:35>7[ ;5N5)†eaW +^G@%`Y aY?+?+?3?9999333210# #"'5326!! ! ! \|jD119M=Z};> Od`@5    iYP  iY?+?3?9/_^]]+9933333310!#!! ! !32654&+3N5afwwt+qlmhs$R@, ""%&   ]Y  ]Y?+?+???39933333310"'#!33632! !"324&p+kҘ)Z}%qhkte;JTh!R@c    iYF!L I    iY iY iY ?+?+3?9/_^]+99/_^]_]+]]_]q_q]q+9333333210!!!!!#!.54$!#";| x12юVdaps )0@Z!! %..% 12  -fY-i- ----$$bY`$$$$ * *_Y 'bY `Y?+?+?+_^]?9/_]+99/_^]]]+_^]99333333210"$'#!.5463!>32!3267;#"%"!.!-lo0P/ebPnYKUuanr`-sR25딂*.('FOI\{qq{`B@!    ?3?3993333333310)!!'77!'`6 ēsJД<ωپsC@"     ?3?3993333333310!!!'77!q_71{fFP䱌p7^0mX,d@< #-. jY jYP` + #+iY+!&iY!?+?+??9/_^]]+/+9333310632#"&'32654&#"!! #"'5326!k0nJ5J>_T@:35>7[ X' ס/ί caW  ^(T@. )*aY ''`Y'#aY aY ?+?+?+?9/_^]+99333321072#"'32654&+!# #"'5326!^Pzr-y1t~ \|jD119M=#}3y O$@j !"%& jY ! !iYF!!!!!!!L!;!!!! !!jYp/ #?3?3/9/]]q+9/_^]_]]]]_]q_q]q+_^]/+9333333310632#"&'32654&#"!!!!!!Hj0nJ5J6$6' ס/Ͱ w= ^"@N  #$`Y$ Hf$ I aY ! aY ?+?3?39/_^]+9/_^]+_]]++933333331072#"'32654&+!!!!!!Pzr-y1t}V11}33^RVh 6@  " iY  jY?+?+??933310!!!!!h LLTo^ 7@   `Y  _Y?+?+?933310%!!!!!ky^V>@!  iY "jY?+???9/+9333310!!4&#"!!>32buOv6[ Ljk *q3'ǸoD@#   ]Y_Y?+?+??993333310%!!4#"!!3632ϴr1f%Z <@%   K {  @ H  /_]+]q22939910#'##'##'5R8127117PXffffX bu@K    @  @ P      sY  ??+?9/////_^]^]9993310>5!!"'57557!%%;nL+??Jo {sDDDD`ooou=G@LG.L@X\9Bga@Ga5@X9G0@G@#G@ ^ ^ v H~ "   D *b ( \ > <N  4 Copyright 2012 Google Inc. All Rights Reserved.Noto Sans UIBoldMonotype Imaging - Noto Sans UI BoldNoto Sans UI BoldVersion 1.06NotoSansUI-BoldNoto is a trademark of Google Inc.Monotype Imaging Inc.Monotype Design TeamData hinted. Designed by Monotype design team.http://www.google.com/get/noto/http://www.monotype.com/studioThis Font Software is licensed under the SIL Open Font License, Version 1.1. This Font Software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the SIL Open Font License for the specific language, permissions and limitations governing your use of this Font Software.http://scripts.sil.org/OFLff  34566778:;YZ[\_`ders}~NOGHTU > ? W X o 45Z[  2`bddss!#$$%%&()+,-/1256689::BNHIJJKQRRSSTT Ncyrlgrek$latn4 kern8kern>kernDmarkJmarkPmarkfmkmk|mkmkmkmk        *:JZjz  &b ' *2 , A Q R _ ` c  fTg dF`bddss  %(3!-:/6G8:OBNRHT_%$=D]4KBj77NNSV\_27 BI^alq~!WYZkl""(UZW]f]kngqk{QQbhssvvl $****0*****************6<***BBHN*6**T**TT****Z**T`````````````ff*lT* &,28>DJPV\bhntzt, t"(.4:n@FLR:X^.tdjpv|PP4Pvv| @$*06<$BHLNTTTZZ`flrx~~~>DDDD,,,,4444tFLtttt &&,&28>D@2J2J2J2JPJD@D@D@V@\b:\bhnttTntz(Rt:,~^~ "(.4:@,2FL&,2RDX^RDdXRDX8>jpPv>D|np4nthnPvhnthnthntP .$*0J2J6<BHNTZ`flrx~ftt:t  ,D@,@,D@@,@, &,26t8B>t"DN"DJN"DPNV\bhn&t26&t26z26t\B|(@(t^t~JtD 8>PJ"(.4:,@FLRX@B^dtjpBt\Bv |n@n@@n$Rnn6@$:l` >D\$b*40P6>Rn<B$HNTZ`fl@rX4x~4 vtJB"HJNRv: &,28>DJPV\bhntzTtD,2D@^4Nv$bn,b$*,b0$ "(.4:@FL RX^djpvD|TtTjt~$D\D62fbfD@D@@2b :$*06H<TjB^"2H,tNBTZ`flrx~hntHJ, JZvR~,tB(vtv@:@X &,R:X:2t^R^R^8R>DJPbJVbt|2v\tbD$P|hntzP$$`~\~~~& >4>>>|   @"(.Jr*`64$:HJ@JFLLRRRRpX^F,d4jJRpv|P:RRRRp8$   :n:X@ jp v$~  HJNv  n $ * 0 6 <T|| Bv$ HJ"V@:n N:X Tdj Zv$ `P f  l Nv$ r x ~  <HJ<(v": $^ T   ^P   T J :n@ : F 4 F :XR :X  :X  :X !:X!^ !^ ~!j!!! !&@,2!,&,!2"!8,2!>&,!D$&,!2"8>!JP fb!P!V4\!\!b\!\!bhnP!hn!nhnPhn!P f!tz!z l!"!"! N!!f!!!!!t! !t!!!t!!! !!!!b! !! !! !,@F," T," T" \$""&26"*2""!,"(".!>"(".t"4B!"":"@"FHJ"L"FHJ"L""Rb"X"^6"d"jB"p"v"|"""hntPhnt""""t"":~XOfdtL~L bXT4X[S|FCD|AP /< lHQ:g:jIk0hvg\8]:h8h9@{h9Lzv HGm%Pl0R bbllAl//llLk@kkx@\]@]9z@@zG@ $k<Dng,lghb]N],X<b"H,8X6@6lfb64<TD@ 09[<9,<9|XnpSnl<0<{C9hD<9hlhA, <l< nl/0zz,`L,4< <,pH,H:> >QT0Lx<v<m,G,l,\hm@lm|@D$(D kPXb ] 94P[ l/ <zPv LP jGP:,)g@EFTh`W,h|,,R,v,lvx~4w_xhTth%!v]2&55 6,@ `@Fp@n<hV  .8p@Dw@N$[ {5IN@ISS@5 + 9&1,>,,<,,@ @(,(\" ,haIppC0G:h@ll|h,,q p:n>,Xpp/X3zdl~Tr0Ghh h$}|RBhhh@D@|jGhMVShhTf@VDxx]t% m\hD]hrllpvp@p0pppph0]p9DpHHHh|HH>>pXp0,0tRll[p{@0S09X,  p ,@H4HlQl::pppg%PG@ImdGdk# ak,,+ Pb`aHNTTHNTZ`flrx~XblbKK/k]TzGfXqGT  $=D]4;CHNOPQ?ARCCUGGVJKWMMYSSZWW[YY\de]xy_{{ab  &,28>DJPV\bhntz\\\zVVVVVVnnnnz\ pt<uu(.nVx> :`L8H-33^^^s^^d^^,^^<^$HL8^@^^ X^ $=D]4679;<*+>FI@^aDH "(.4:@"FFLRX"^"@djpv||^^^^^-7xVx4XLxdxyG,:jV*\#?p?^^^ns%Lp^^J^^f^@^ ;A$=D]4KBj77NNSV\_q~]""eU&QQ'bh(ss/vv0   1      & , 2 8 > D J P V \ b h n t z  "(.4:@FLRLRX^LRdj@Fpv|@F            J J J J                   $"(.(.(.(.LRLRLRLRpv@Fpvpvpvpvpvpv@F@F@F@F      " " " "   *0 (. (. (.  (. (.6 26 26 2 , 2< >BF 8 >@F JLR JLR JLR D JLR JLRHNT.Z VLR \ bX^X^` nfR h nLR h nLR h nlr h nLR @F @F @Fx~ @F pv pv pv | | |        @F @F @F @F @F @F          LRLR zdj                           (. (. (. . . . . (. JLR D JLR pv pv v v v  v pv&&&& @F @F,,,,    28>DJPV\  "  bh>Dpv  ntz &6 2  D J \ bX^ @F      (.(."(.4:@FLRX^djpv|   JLR pv @F(.$ , 26 2 b^ pv pv.(.4:@6 2 @F     (. (. JLR JLR pv pv | | @F @Fz< >BF    (. pv   " h n $*06  (. P VLR<B |  "HN(.(.TZ`fLRlr@F@x@FLR~LRdjdjdj@F@FHNpv|||||LRLRLRLR@Fz$*$*$*" lrLRX^$*$* &,28>DJPHNV\bhnt@F@F4:dj@F|zLR~z4:X^LRdj@F| (.LR"LR@F    "          . .  (.  (. (. &:6 2< >BF 8 >@F< >BF 8 >@F 8 >@F D JLR JfR b^ \ bX^ \ bX^ h nLR` nfR h nLR h nLR zdj t zdj @F @F @F @F  v  v  v  v   | | | |          @F @F @F BF BF          @F 06  h nLR h n  i<iJJ(N``{{ddPP^^HHhh  33VVBBqqyy000{0000^0 00VV1100B0,00q0mm;;H0h0000ooh0h0h000ZZJJ//99HH  ooJJqq y0 y  ++ ' 'P00 ybbhh!!{{))33ffBB==//\\LL  \\mmJJ11DD`0d000y030V0hh0VV $=D]4KBj77NNSV\_q~]""eU&QQ'bh(ss/vv0   1      & , & 2 8 > D J P V \ > b h n h t z h h h     & & & & & & D D D D \ , b b b b b b n t t t t h b b b n n n n h t t t t t h h h h      t        & & & 2 2 2 8 8 8 8 > > > D D D D D D P \ \ > > >  P P P \  b     b b b b b b b b b b b b t t t t t t t t   & & & & & & &           D D           \ \ \ > h " ( h . 4 n : ( h @ F J L R   X ^ d & j p v h 2 8 |   >  J \ ^ > t t  h          b  & D t h h  & & t     h   b b t t   & & 2 2 D D F   h   > b t & \      n  >   D J t   h 2 \ b h h h n $ h h t t *   0  h h 6 < B  H  N T Z ` ` f f F l r      n & x  6 ~  h             h h z h ` h    < h  F h h z  h  b h h t    n  h h h n h h h h h t t t t t z h            & & & & , h , h 2 2 2 2 8 8 8 8 8 > > > > D D D D D J J P P V V \ > > > b     , 2 b  J00`000{0d00000P0000^00H0h00 0300V0000000B0q000000y0000000V0100m0;000000o000Z00J0000/009000H0 0o00000J0q0 y0 00+000 '0000b0h000!00{0)0000030f0000B00=0000/00\000L00 0000\0m0J001000D00000V0 Z`"$&(*,./125678DFHJLNOQRUVWXL"LRX^djXpv|d H40NAbl4@D $=D]4KBj77NNSV\_q~]""eU&QQ'bh(ss/vv0j1jpv| $*06*<$BHN*TZ`flrx~|****B$BBBBBB````xHxvvvv| | $$****066****$$$BBB**TTTZZ`````lx~ &lllx00<B`,,,,,,,,*28>DBBBBB>JBBBB>PV``````V`\xxxb&hpnv|tB z~T6*fHZx~ZH    *B` " (6 . 4 . 4z : @H$,,**BB**`` F$ L R X ^ d jBx p vZ | v p ,0 *x   fff0 f$ *   $ B    H * $ *f 0 6 6 < B H N`BBr Tr Z ` f : : l r x ~  0 N l r    <$H**TZ~  ~ * H     H   & , 2 8 > D J P V \ b  h n Vp t z  N| t 4 ,,  $$$$$ *66 8 8 <<$$  BBBBHH*  T TT Z    " ( . 4 : @ F``f L Rllrrx~ X ^ dZlx**Zf jCz >4p\HH IlzZLHH\HBHppp'?)pp84HnH6pplppfpbHpH ,H HtP63SH8O  nHuHHbHp pHNvH=HHHp/H&HHH=&HHN.MHHhHH@HH+Hn~HHDHHJHLH-H.cmHHIH%zHX~`D>FH@d ppppp ppplpbpp\p&pppjv4 6@EGIKMQSZ ]]4:6<BHNTZ`flT6rfx~VVVVqVVpVhVBVq V7VVVVV p`bss!#%% )+!/1$66'::(BN)HI6KQ8SS?`bss!#%% )+!/1$66'::(BN)HI6KQ8SS?@@  $$ *06**<BH****6NTTTZ`fl<Tr`*xf~`*N~x~<xOt`T~h~T<xhOhT|0d@ djdd  $$&(,- 25"89&JJ(RR)TT*dd  $$&(,- 25"89&JJ(RR)TT*+    $*06<0 6000BHN6*00HTZ666666* +~t`V4 $ BHfl )`dos""PEKNO<-2"FEKNOFtsdtdpqt2200 0"""<"^^4 ,TT,T 0 0 0 0 0 0"""""""4<zTT 0 0 0"",,"""^T4T4 0""z   " !"!<!B!DFHIKKNNPS UU$WW%Y\&^^*+78=DJNORST^_`adnostwxyz{|}~$(**,,..0022446;==??CEGGVV[bddffhimmooqvxy{|~~      !! PQ UV]]__ggimosuuwwy 1P\bhjlpq{AFJLLNNPPRRUUWWYY[[]^cceeggiikq~//$79:< DFGHJPQRSTUVX  !$&+-/13568 : CDFHJV_biyz{~ TUV]_gopz|  "#$%&'()*+,-./013579=?AGIKOQSUWY[]_acegikl n p ~-Z&*24789:<$&*,.02468:GfmqrsuxQ\^iy{}    FHJLNPRTVXZ\^`bdfhjlnp~7$&q~< &*-2479:<$&68:G \FHJLNPRTVXZ\lnp~4$79:;<=$&68:;=?C U "$&(*,.0lnp~%&*24G\FHJLNPRTVXZ\-<$C U "$&(*,.0N &*24789:<$&*,.02468:G \^FHJLNPRTVXZ\^`bdfhjlnp~!~~$;=;=?C~ ~U "$&(*,.0"$&*247DFGHJPQRSTUVXYZ[\] !$&+-/1357<>@CDFGHJ TUV\]_ "#$%&'()*+,-./013579=?AFGHIJKLNOPQRSTUVWXYZ[\]_acegikm~$C U "$&(*,.0"$&*24DFGHJPQRSTUVX !+-/135CDFGHJ TUV\]_ "#$%&'()*+,-./013579=?AFGHIJKLNOPQRSTUVWXYZ[\]_acegik"$&*24DFGHJPQRSTUVX] !+-/135<>@CDFGHJ TUV\]_ "#$%&'()*+,-./013579=?AFGHIJKLNOPQRSTUVWXYZ[\]_acegik%&*24G\FHJLNPRTVXZ\   YZ[\]7<>@ m  < << <4FGHRTH]3579=?AGIKOQSUWY[]U( (DFGHJRTDFH( (V]#%')+-/13579=?AGIKOQSUWY[] ( ("( (   ( ( F@F`F( (  fmqrsux QV_bdipqrtux Q%V_bfimsvyz{|}~ !qrxQV_bi -V_bfimsvyz{|}~ !Pfmfms~~V_bi~ ~ V_birx Q V_bfim    y~ y~ y~    y~ 6  ky}     ghijnoprtvz{|~   i{    #iy{  N22 giop{|22 /  ky}      oy  }  n  = opwy}  !~~~ ~ops7 opw}  % gp| g|       p'  j~       I(W(Y2Z2[2\22%('(72224(5(Z([(m2(I2W2Y2Z2[2\22%2'272224252Z2[2m22  y}  5  gjz|~      op ghinoprtvz{|   ! gp| %  y}        %nixz{  g|   )  y}      j~  }   ghinoprtvz{|     p*  y}        }  )  jy}~    @  osy}         o}    +  oy}   Lcyrlgrek"latn0aalt2ccmp8ccmpBccmpLligaVrtlm\rtlmbrtlmh 0@P`ph< T"*2:BJRZbjpx&.6<DLT\djrz^fnv~ (0 $*2:BJRX`hpx$,4<DLRZbj                           LMW`bss!#%% )+!/1$66'::(BN)HI6KQ8SS? (B~FPZdnx  (2<FP ` a ` a ` a !` "a #` $a %` &a '` (a )` *a 3` 4a 5` 6a +` ,a -` .a /` 0a 1` 2a 7` 8a 9` :a Y G k l m j n o '*,./0I 4L5OZIL[IO  ; < = > V 7LMWlinphone-desktop-4.2.5/linphone-app/assets/fonts/NotoSans-hinted/NotoSansUI-BoldItalic.ttf000066400000000000000000010654401376717241300316210ustar00rootroot00000000000000GDEF4(GPOS .GSUBF #a `OS/2VB`cmapO'hcvt 09fpgms-p. gasp#glyf?_Lhead"[z6hheaT$hmtxTbj%locafB:0%maxp [x name|Dpost]f prepq6\_< 4( X  X o pRTi\2K33f  GOOG!X ^ J+)h3sD Jm\hmH)H^hBhhhhhhXhNh7hVHHhmhmhm\5{j5V5?5{55%5 5 5{5{5=)?'J^wh#3FoZ%ZZuZ%%`%`%`%=%%ZZ^%H^ofN}?'shhmJhhhshXhoHhm)mhm;\o=H1 a a ){V5V5V5V5j% 5{{{{{hd5FZZZZZZZZuZuZuZuZ`%`%`$`%H%ZZZZZhm+oooo's'sZZZ{Z{Z{Z{Zj5Zj%ZV5uZV5uZV5uZV5uZV5uZ{{{{5%5%`%`%`%``%%`5%%%5`%%5`%5`%%5y%% 5% 5% 5%4 5%{Z{Z{Z5{Z5^%5^5^%=)=)=)=)?H8?H^?Hoooooo'N}'sJJJ hZ)Zd+=)o7oyHo`BTo;oo5oVH"-""N>"o>G55V5J5{5 5 5+{55X?{Z'%`wZ;7'Z%d`%ff\Z^ZZ^wZjwwZ`wZwZV55{=)555555;V5) 5 55 55{55{?{5b5V555 5ZmZZuZ1oo%T%Z%Z=%'sZ?j=j^jd\mjh%uZ%Z`%`%`1%%'sj5%'N}'N}'N}'s)))3+sj9wswj  1 s H}hh9h){)wm a \ f L {hmdbLhmhmhmhmqH%H%o=`{/^{RVyHTT`ju^ 5=%ZhX%%-{%Z3jbV5 5uZo1fj=5%Zd5%5%1ww{Z3^f3^f {}Z{Z1Z1f{ZhH-q?oZo;))5j5s5 T5%Z)15%5Z5%{/J!5H%)5%B5%{Z{Z?h%fLu\bb5%;=J;=J5%F5%!5H%b5ZZ)ZV5uZHDu3HDu3)1q` 5o 5o{Z{Z{Z's's'sb5%5mj?=Z=ZB+5/%{ Zb^D'5ZZZZZZZZZZZZV5uZV5uZV5uZV5uZV5uZV5uZV5uZV5uZ`%`{Z{Z{Z{Z{Z{Z{Z-{%Z-{%Z-{%Z-{%Z-{%Zoo3j3j3j3j3j's's's6`FV`?HV%f5%!}}{Zj%Lf?ZVHD)?3{R%f5%`y 3%{j#Zf5=)X+H^fH^?owsJqq=d?fwH!!!fJ 5 5dZ55%5j55%Z`%{Zooooou3ZZ)Z{{5%{Z{Zq` 5 5dZ{5) 5%ZZV5uZV5uZ``%{Z{Z5^%5^%oo)m5%5ZNTJZV5uZ{Z{Z{Z{Z'sR%f#Z#Z{L%/?DV5uZ`{Z^^'sbZ%%ZZL3u33'1BZ`Z5^Ro%%``R)#`%=j=j=%#%\%ZZfFZ^^^^^H%%`#`#q`HHD3wN'Jfw``H){Z1Z%`%Z/uZ%ZLZ/^^^5%%%!%;;'!jwjsTjTjuuHHHH#oo#VjooTT"T7u)V})9XXXXXXXoLwjPobdHs##mEI\n-52qjh'mj}p_N`H3L;%7D!Bj )# BFN\ZHbZ5ZZ?5/?3T;=jZb5%V%''{ZD9DZ`{Z5{ 5Vd{T{Z'N}m3)R`9`-u9`J9H99V?\?\?3BbZ9LDjw7D7h{o9//99wBLy7)){Fhd1oZd;!5/%jy}\)3}V.).V3Aa1wZ%=w^RFHu^`%Z%H%`=%%^#f?ZZZuZ'13`%`+oH+%VfRjRj\\ ow #Fyyy; udud5%5%5%{Zj5Zj5Zj5Zj5Zj54V5uZV5uZVu*VuV5uZ?5%{5%5%5%5%F``%5%5%5%%5`%5`%5`G%` 5=% 5=% 5% 5% 5% 5{Z{Z{Z{Z555^%5^5^5^I=)=)=)=)=)?H^?H^?0H?Ho@:ooff'N}'N}??'sJJJ%H^N}'sZ )ZZZZZZZZmmVV''''''f=o==o=%%%%%%%%TfTooq]q]````````!p)o)RoRf|f|ZZZZZZpoowwwwwwww|ZZZZZZZZpooL|L|ZZ''%%``ZZwwZZZZZZZZZZmmVV f  Ho H Ho H 7] 7]ZZZZZZZZ bp b o ho h | |ZZZZZZZ)u)o;o% PXNP`5``."6` SwwwwwwYVJRZZZZZZPyPf)L!LhJhwN5HbZZ%;^jBF=%+?P) {{h7 k Hdhm#f{mmb))s+jVFR?;?;fBhf%`%5H^!5%'5%J{BfPw}Pm5#Z!fj3/JyH%/J -h{VVVVVNVRVNVNVFFV5V5VPV-VH-V%V%V%V'V/%VVV5V5V/)VPVLVLVLV^LVVVVVPVLVFVLVLLV/V9V?V?V??V5V5V5V5V55VLVLVLVLVLhVLVFVLVLVLLVVVVVVVVVXVVVV\V7V7V7V7V77VHVFVFVFVFFVVV9V9V99VVVVVLVVVVVLVLVLVLVPPV/V5V5VV)V/V'V%V%V%%VHV-VPV5V5-VFVNVNVRVNFVVVVZZZZZZZZ````````wwwwwwww````wwww5 5{3333wdwy333333335y5%R\5%5;%5;%hLhlhl# \`` ~ac67"#ou~  OP\_'=?EMWY[]}  " & / 0 4 : < > D ^ p y  !!!!"!&!.!N!T!^!!!"""""""")"+"H"a"e###!%%% %%%%%$%,%4%<%l%%%%%%%%%%%%%%%&<&@&B&`&c&f&k&o),m,w.!# bd78#$tz PQ]`>@ HPY[]_  & * 0 2 9 < > D ^ j t  !!!!"!&!.!M!S![!!!"""""""")"+"H"`"d### %%% %%%%%$%,%4%<%P%%%%%%%%%%%%%%%&:&@&B&`&c&e&j&o),`,q. ^IvedAeY @SQzKIzx?wZI we%" {ob`aa` kLP>:6&$&8F0(.@@<"$ IJ$%KLM`abVPQWXYRh X Y Z [ \ ]STUV     ;<=>r i,-03PQ45Z[@G[ZYXUTSRQPONMLKJIHGFEDCBA@?>=<;:9876510/.-,('&%$#"! , `E% Fa#E#aH-, EhD-,E#F` a F`&#HH-,E#F#a ` &a a&#HH-,E#F`@a f`&#HH-,E#F#a@` &a@a&#HH-, <<-, E# D# ZQX# D#Y QX# MD#Y &QX# D#Y!!-, EhD ` EFvhE`D-, C#Ce -, C#C -,(#p(>(#p(E: -, E%EadPQXED!!Y-,I#D-, EC`D-,CCe -, i@a ,b`+ d#da\XaY-,E+)#D)z-,Ee,#DE+#D-,KRXED!!Y-,KQXED!!Y-,%# `#-,%# a#-,%-,CRX!!!!!F#F`F# F`ab# # pE` PXaFY`h:Y-, E%FRKQ[X%F ha%%?#!8!Y-, E%FPX%F ha%%?#!8!Y-,CC -, %EPX ED!!EDY-,!QX d#d b@/+Y`-,!QX d#dUb/+Y`-, d#d@b`#!-,KSX%Id#Ei@ab aj#D#!# 9/Y-,KSX %Idi &%Id#ab aj#D&#D#D& 9# 9//Y-,E#E`#E`#E`#vhb -,H+-, ETX@D E@aD!!Y-,E0/E#Ea``iD-,KQX/#p#B!!Y-,KQX %EiSXD!!Y!!Y-,EC`c`iD-,/ED-,E# E`D-,F#F`F# F`ab# # pE` PXaYh:-,K#QX34 34YDD-,CX&EXdf`d `f X!@YaY#XeY)#D#)!!!!!Y-,CTXKS#KQZX8!!Y!!!!Y-,CX%Ed `f X!@Ya#XeY)#D%% XY%% F%#B<%%%% F%`#B< XY%%)) EeD%%)%% XY%%CH%%%%`CH!Y!!!!!!!-,% F%#B%%EH!!!!-,% %%CH!!!-,E# E P X#e#Y#h @PX!@Y#XeY`D-,KS#KQZX E`D!!Y-,KTX E`D!!Y-,KS#KQZX8!!Y-,!KTX8!!Y-,CTXF+!!!!Y-,CTXG+!!!Y-, T#T[XCPCT[X!!!!H+YCPCT[XH+!!!!YY-, T#T[XCPCT[X!!!I+YCPCT[XI+!!!YY-, #KSKQZX#8!!Y-,%%Ij SX@`8!!Y-,%%Ij QX@a8!!Y-, #Id#SX<!Y-,KRX}zY-,KKTB-,B#Q@SZXB TXC`BY$QX @TXC`B$TX C`BKKRXC`BY@TXC`BY@cTXC`BY@cTXC`BY&QX@cTX@C`BY@cTXC`BYYYYYYCTXBY-,Eh#KQX# E d@PX|Yh`YD-,%%#>#> #eB #B#?#? #eB#B-,CPCT[X!#0Y-,Y+-,-@ ;K[PZUZZ?ZOZZXUYPXUX@XXTUUPTUTVUWPVUVV VUPU_o߉ \PMU+M;M MkMMMMNUJPIUIII7IIIIKUGPFU`FpFF;FFKUOPNU0NNKULPKUKK?KKSPRU?RRPUQPPU@% F!3 U  p   {  U3U}vs@us2+ttttts]/3U3Utdtdtpi<ooi$4nTmmmm{mm mFjjjji]3UU3U?Tdh]6@ g;>F$gggg@ g'Fg g@gFggtg9fYfiff;eeeete d]7c]*Kb bbbaa ``+```` `&)F __@^.4F@^%F ^F ]?[]]]]]]K3U3UU3U0UdUoTS++KRK P[%S@QZUZ[XYBK2SX`YKdSX@YKSXBYss++ss++++tstu^s+++^s+^sss^st++^ssussts+t+u++t^st++++tu+stuu+u+sts++++stu++s+++ssstu++++s+st++s++stu++st^s++^st+^ss++^ss++++s++s+s Pu^{VF3`5 ++T 66662r Zj@  6  X 0JJrV"(|P 2 pPD|:x x  !4!!"F"l##v#$x%%l&&&'<'((())*B**+t, ,->-./"/011z11223T34556J667L78J889909::6:X:z:;L<<<<<^<<<<= =.=>>:>\>~>>?<?@ @,@N@r@AABB&BFBfBBDD,DLDlDDDDEE8EFF.FNFnFFG\HH H@H`HHI>I`IIIIIJJ6JVJxJJJJKK@KXKhL:L\L|LLLMMM2MTMtMMMMNN<NTNtNNObP P.PPPrPPPPQQ(QNQfQ~QQQQRHRjRRRRRSSFSTT&TFT^TtTTTUXUVV(VJVjVVWXXXYY&YHYhYYYYZZZ@Z`ZvZZZ[:[[\\6\V\x\\\]]*]B]Z]|]]]^^&^F^h^^^_6_`bb&bHbjbbbc cXccd,ddeef*fffg"gHgnggghhh$hXhhhxhhiiiiijjjjjkJkZkjll*lmTmxmmmnn&nJoop<pqrxrssttttuuvXvw~wxhxybz z{,{P{r{{{{||}}}}}~2HXhx2T"2BRbrp.,<h 24 *:JZ | ~xN8Z~:J NJx.>N@4FV&d0H`xF~bVBBBBBBBBBBBBBBt<L6^>flö@ Ŋ(H&ǜ,ɚʆb̈.ϰ^n~P8Ԫ<`xՐT~ڐ`ۼ\ܠޘL. <(@X( jNZx 8Pt\>@NBtF"8Z~.LR(Jj4Vn<L\ ,Pr J      8  Z  Z jz R>RJ,Np0T"Fn(Lv4T|8h":Rj  : ^    !(!P!r!!!!"":"Z"r"""""# #@#b####$$ $8$P$h$$$$%%b%&D' (0()J*D+8+z+++,--.R./^/011"12.2344,55r6B6778989::;`;;;<=x> >?B?@@AXABJBCPCD^DEhFXGGGHVI(IJlK KL,LZLMMMVMMMMNN&N>NVNxNNNNOO@O`OOPPHPPPQ0Q@Q|QQRR>R`S~TTTTUU.UFUpUUUUV V"VDVdW WWWWXX<X^XXXXYY2YTYvYYYZZ&ZJZlZZZZ[[*[\\4\\]r^$^^^^__*_V_|___``6`Z`|`a8bbcdeRefggh\hiNijknk~l@m2mn6nopRpqZqrrsNstnu(uvwZwjxxxyzz{|},}~FB~8l|ZtH$h^6Bp*F~fJ&($ <@,b@& >r6(v08$l.^"4Fb~0fJ,h*n$N`p*rHrn 2Z2z <l*P6t Nx0BTx\R²(:nÀðn8DƄƸɊʈP@x͊ͮ<Ζ<f"ѪҬ JӒӮ 8\l"ؼ:b܈R߆.p(^ DN:JZjz0XhR<`:l$jH nJ(:^8l*~ v64: *   R  t     >ND@,| jxB\`  "#N$j%&'()n*H+D,L--.B/P/001(123v4D5667 78|9@9:;@;z?l@nAhBdBCDDExEFPFGGHJHHI"IJJLJK~KL L<LMNNNOPXQQrR RS2STTLTUUV2VWPWXYYPYYZZvZ[2[t[\\:\R\j\\\]$]F]h]]]^^^.^X^^^^__<_f___` `.`P`r````aa*aNafa~aaab&bRbxbbbbc cTclcccd d@djddddee*eLede|eeff8fhfffgg:ghgggghh4hVhnhhhi i@ibiiiiij$jHjrjjjjkkJk~kkll>lhlllmm8mhmmmmnn"nDn\ntnnnno oBodooooppPpzpppqqqqrr8rZr|rrrss*sPsvssstt8tZt|tttuu.uTuzuuuvv(vJvlvvvvwwDwjwwwxx(xLxpxxxyy$yHynyyyz z8zZz|zzz{{({L{r{{{||(|J|l||||}}>}d}}}}~~>~b~~~~>d>^~"BbFn:h&Z,V0^"Lv&R~2`2Xn@bz&6Hp@d~Bd<^xp<\|(Ln|Lv(Lp*LB\@(8l8Z"&nvf0 ,L2L$\(|6B,V`*d"d\ Z4Z~: ZZ°>ðĔ.Űlƚ$RؠBٌٸBn:݂~\4j| l|tNLXTb:tXvz&`XF.~`T.(r ` N,$fZH,tj  N   H   $ j   j   >  8l ZT..tPJ(|fL4&rjJ8 jd >  !4!!""f""#N##$0$$$% %F%l%%%&&(&L&p&&&''$'J'p'''((.(T(z((())<)d)* *0*+,-./0012234<456|7.7890:V;J<.=>??@A:ABChDETEFGfH(HIHIJHJKRLLL0LFL\LrL  ?2/310!!7!!IhyJh2@ `   }Y ??+9/_^]]q10#!4632#"&TkaDRnYIRZlLEWlK?32/10#!#%GJ)5=@ Y Y    ?3?399//33+3333+3310!!####7!7#7!333337# EtusqF!wuttENhhii3`%+,@= %;%K%-%%%% H%&&sY@H@+4+D+"++++@ H+  sYp@ H-,?99//+]33+39+_^]]]9+33+39+_^]]]910#7&'.546?3&'>54&' ',ђG#!jn?BH?N1#>EP J k B=|DA 3a H>.;=D54#"&54632?_8A^pzo{@9'H.7)H/lyj}``mJp]ana`d۔"D$0@\ZjI:+ $*$:$$ $$"& 6  %I:+ %% %+nY"iY??+?+9_^]_]]]]33]9]]]9]]]]]9/910)'#"&5467&54632>7!327>54&#"-HߝLǩ,I*,XF[GsjhqU<(BIbv÷a᥎9mǸP3kNAV;q;h<93]I.\% ?/10#%GJH  $??10! #JuS?  mj $??10!3jtZ!3B% ?10%% '-7uqZVR!+IQ\qm% -@ YW`/o/]]qq3]3+3310!5!3!!#nodq@ @ H/+]10%#6yvJxO)j@oYoO/]q+107!)5 5{9 }Y ?+1074632#"&kaDRnYIRsZlLEWlK ??10 !)JBV @ sY sY?+?+10#"&5$3 "32654&Vͥ#VP`7FR\=#tsuof !@  ??9/]9310)67'3ϴ#) i҅6=N\J*@  vY vY?+9?3+9310)7>54&#"'>32!>+ݴREBfR8TKOCUp_ġk P'_@<uY4I$IN^ ! I I "%%sY% sY ?3+?+39/++_^]]+]+qq+910#"'32654!#732654&#"'>32PT].IVN|ي}yuO 23q|nCJdQAP :@ HsY O H??3+9/]3+39+10#!!7!3!7>7#??07ê1: 8 .Q//i:#Rch3@sYvY sY ?3+?+9/+39102#"&'32654&#"'!!6oԏu=smfoh7XHθ.# c{^^!NX&*@ sY sY sY?3+?+9/9+104$32&#"3632#"&2654&#"Xz,}b3Tk>sĝc}CE32654&"654&{a\ttrdU]mILZ{OTb4zjȪ*wh-|[Q_kUIu]IEHDNVD&4@ sY  sY sY?+?+9/_^]9+10#"'3267##"&54632"32>54&Dpot>oAAe7KD7>54#"'6324632#"&tu|C2q\ױ9l^Hn_DQnXJR咹OTV5w D}Sq[?aV[kLEWlL\F8D/@ @@ C9  .!6(.%?3?399//33333]310#"&'##"&5463232>54&#"3267#"$5$! "327&ŀXq 4|P𔹎j :BtE uw>jRI1-H9$HئMFPC7\,A Dk(.Z8gYAJ @ iY ?3?39/+10!!!! /#J'u'64\D`^k5_@;oY)"I$ I I I  iYiY?+?+9/_^]+++]_]+_q_q+9102)32654+32654+ꦙdw5yyʴu na[Htg{7 @iY iY ?+3?+310"327#"$32.Ӏ\}ovjˢĴMM+-<;&5+ @ iYiY?+?+10#!! 2654&++=5'۔|sch'H5 I iY@&I' I I I iY iY?+?+9/_^]+++]++10)!!!!!f526C7#P5 @ iYiY?+?9/+10)!!!!f5.6O8'{m0@iY   iY iY?+?3+9/_^]+10!# $!2.#"327!3sJW񉑖L^B5.!& c(0ͱ+5 3@!iY I) I I I I ?3?39/++++++10)!!!!!oΆ)52yy1w= @ iY  iY?+3?+310)?'7!Ly$ɘ%%ɜRRRNRR  iY"?+?10"'53267!^]XLc{%14Rydq5 @  ?3?39910)!!7!u}m52iPF>D5iY?+?103!!5526J5@    ?33?399310 !!6#!# !!H%$I =85AqEJmX5@  ?3?39910)#!!367! 5eT#!R;֑Pߢ{ @ iY iY?+?+10# $32%"32654&\ysyypA' >Ǝ5 +@ iYP`iY??+9/_^]+10!#!!232654&+֜m5}aa &t]W{ @iYiY?+?+910!# $32%"32654&\ysyyp!bwH' >Ǝ55 iY@I I iY  ?3?+9/+++91032654&+ !!2!N_fJw5g-ruRRyŞ71)V#,@" iYiY?3+?3+999910#"'32654.'.54>32&#"݇p~2cp|ٴmSjBsyxZlUJ+A8JcpqcJZJ=[KP@ iY?+3?10)!!!;77@  iY?+?310!"&547!326791{ NHBiJ3q?3?310767!!!3<'3+N9pJ5@s3@  ?3?3399310!!3>7!367!!'474=-!Q q 5LJ5y145]3~Jq^Zy @  ?3?39910)!!!dt@@kX+?@ ??393310 !!!svVww8fPy/ $@iYiY?+9?+910)7!!!+& 5)T1$?3?310!!#3'}- ??10!Jw$?3?3103#7!!\#-)qT#5?9/39103##j߮oJyFH/310!7!{6!@ @/]q10#.'5!G$7$OEEZs '@  ]Y]Y?+?+99??10"&54632373#7#'2>54&#"a'9CENM?D{ICgTPG]tXX%h!&@ ]Y]Y?+???+9910"'##!3>32"32>54bR:J->)+NL>JxNJACzKubHؾuP`uZs@ ]Y ]Y?+3?3+10"&54$32.#"3267ו\6hBUM[QLE[H"߀`a/#OZ#'@ ]Y]Y?+?+99??10"&546323767!#7#72>54&#"Rw5L-G!FvOKAD{IeJZnUfWNuP`tZBs!i@@  bY?   cY   hY ?+_^]3?+_^]9/]_]_]r+93_^]10"32654"&54$32!#3267X-3g`WesaS_RU[i&0V%*@ cY ]Y]Y?+?3+?3+310"'53267#?>32&#"3#-hF=6=\̣)ðhPE@9F 1MPZőTT1PA>s,/@&]Y]Y ]Y??3+?+?+99103#"&'32>7##"&5463232>54&#"4h[h8HSZ@DtNJ?G}GL^)V_a^LֿbE_}P`yXX%m@ ]Y  ?3??+910)654#"!!3>32Ӊl\+bJ-'*A>dD3{1M]Ik%@  fY???+10)!4632#"R-_WILX\^WY>:Pc @fY]Y?+??+10"'5327!4632#"ZhF=5$.MX_WILX\)PWY>:Pc%@ ??399?10! !!!3XxJJ- % ^HJ9v,% ??10)!RJ-%s&'@"$$ !]Y?2+3?3393?1023>32!654#"!654#"!336L+Fhӊb^(`Ӊb\+b sptLhD3{/D3{1^%ms@ ]Y  ?3??+910)654#"!33632Ӊl\+b ΊD3{1^䧛IkZTs @ ]Y]Y?+?+104#"32>%#"&54$32%KwKKxC/z}{ہMhs!'@ ]Y]Y?+?+99??102#"&'#!336"32>54-Sx3 HV :JyMJACzKsJYJwP`uZs$'@  ]Y]Y?+?+99??10".54632373!>7#72>54&#"XMV:9/4:H=FuMKAD{II_gKY^LwP`tXX%s@  eY?+?9?102&#"!336J;%B-7t%j s  ^s";@!     cY cY?3+?3+9_^]]3310#"&'532654&'.54632&#"=kEPfJ^y`ɢcv9F@X{nq#ZA8+D4D\_T3+';-?^oL&@ cY@]Y?+3?3+310%27#"&547#?3!!Aao sĄ12s#5~2>TJo^@]Y  ?2??+910!3267!#7##"&547-l\+b- ͊^sD3{㥜]xf^  ??391067!!!@)C'--.R^b}^@  ?3?3?99310!!3>7!367!!47RZ3 DH Q&3 \@^с,=hX^ @  ?3?39910!!!!{Asb-}=!NVs^@  ]Y  ?2?+?310!3>7!!"'5326?f'8 0)GXZ9D0T6^i3U `e1^ $@]Y]Y?+9?+910)7!7!!#?s3+Sd'8@'?O_/_  $ ?3?39/]q33104#7267>;3#"&54?6-z=&T1ZQB-US$C:5'?SaAJqN,E6(y9DE/ #??/103#!&@ %&$?3?39/3310 3"+5>7>75&54?654T'-z>%-]XBo%II)8DETa䪌AI)on 3+E6(m'%}m@ -   Y H@% H@" Y/?/]]3+3_^]++_^]q2+3_^]10"56323267#"&'.V6}6e@jV@^03z=g;daYLB7m$=hîq`K`/+-*710-1)VDO]TK0hs#' %/321047'76327'#"''7&732654&#"6[ji[55}_esT}6mPQoqONof_57Ynk\}}33{}]hMonNPnpX K@-tY tY   ??39/]9]39/]3+3+310 !3#3#!7#737#73!`s7'%//%')hNݲ/@ #??99///3103#3#,7d@@- I-Y-i-*-:----3F3V3f3%35333 3 $$lY! lY ?3+?3+9_^]_]]]99]]]]910467.54632&#"#"'532654&'.>54\n*8ŬR?QQWzx&4̄c[B^ud3>Uf15UE"e9XT28*B&6cs#e:KiF9'C.9.Y43U-\/j3 *@0@ Pp/]q333/]104632#"%4632#"OH}HMOH}HMfNPlIWnNPlIWh%5G@0   o  `p  *"20??99//]]3310"327#"&54632&4$32#"$732$54$#"z]xAb:~~>l^Zm+)׭֭->}6^ZƬ֭)(m4 0@PTH [0N ?^]++9910"&54>32373#7#'2>54#"qgr\dAT' P1-N5XIe쌀ux52ZB\hQJkwoHZ @0 //]3]210%H9ϛgϛgm%?0@ Y`/o/]]qq+9/_^]10%#!5!%#l)jh-5;@ #'..*%%)5*))**)*)* 0??99//]]39/9104$32#"$732$54$#"%###323254&+^Zm+)׭֭^Vm륟XX`aX^ZƬ֭)( M#\pK< Y/+10!7!- X  ?32104>32#".732654&#"][]\\^]][ABZ[AA[q]\^\][Z^?[\>?^_m% i@H Y j Y *     YeFV`p_@/]]qq3]]]]]3+33_^]_]]]]/+10!5!3!!#5!noq;J+K@0   { O _ ;  wFV7 ?3]]]_]q9?33]]]]q9310!7%>54&#"'>32!x#o<3#VfdJn{,`[J[>8*(R9<~aFjef_\9-%@U F4"HX#h%!I}=()I !#I;-G !?33]_]_qqq?39/_]+q_q_q+q3]93]_]_qqq910#"&'532654&+732654&#"'632-fsֲK2}Lb4>"ZTa4-VfRVs!H=:%389((B\o!@ @/]q1067!#OO.VX8>^@ ]Y ??+??39103267!#7##"&'#!!?0Z-b- u3M IV-\T\P3)}jD1W@ H@ He @H   'fvW?3]]]q/9/]+9]+]+10#"'53254&'73VB?>f>O`'t~R"- H1J M@     v  @ H Xhx  @H  ??9/+]9]]3+]]]]qq103#67'ϺT@fmb-Q) *@PTH[  N ?^]2++210#"&54632"32654)apЭ@WP?TFuinozkZ7 @ 0  //]3]210 '7'77on)1N^g31N^g3aJ'&{; ?55a'&{tq?5&u)'H;Z -?55y^$N@3/o_o ""}Y"]Y /]3+?+9/_^]]q99103267#"&54>7>7#"&54632l~zE2q\9n^H`o^DQmYIS^USV7v D}RsY?aVs\kLFVlJs&$CR&+5 s&$vR&+5s&$KsR&+5`&$RR&+5V&$jwR "&+55$,@0"iY "?3?3339/r+10!!!&54632/#4&#"326?A'%qm646**710*6#gA\5Tl^k-33--33o_ iY @2I  ' I  I  I   iY iYiY?+?+3?9/+9/_^]+++]++10)!!!!!!!#9JVP6C7"OP\`X{7&&z35s&(CR &+55s&(v}R&+55s&(K9R&+55V&(j)R &+55s&,CR &+5s&,vR&+5s&,KrR&+5V&,jzR &+55%+ `@>iY.I&I7I' I I  iY iY?+?+9/_^]_]+++]q++3+310#!#73! 2654&+3#+=}7'۔|sK7GcTdh'5`&1RR&+5{s&2CwR&+5{s&2vR$&+5{s&2KR"&+5{`&2RR%&+5{V&2jR .&+55  6@  HH//]++]qr10 7   '՘-1-Ӗ-+ј-՘d& @ #iY#iY?+?+9910#"''7&5$327%"&'326|lyb\{iu[~rTE;^|qAGs LuY E+P%=s&8CDR&+5s&8vR&+5s&8KR&+5V&8jR '&+55?s&<v{R&+55 @ iY iY ??99//++10!#!!3232654+؇>522T3i{''u:9@05]Y0&  &)cY)]Y?+?3+9333?+102#"'532654&'.5467>54&#"#"'53276$NbI.,9kKֻne^5R^FZuBMOU`x+ЭZF=6%/rJ*55+SS=NB5(F>HtDTzB%N9>Igx=ƵZ!&DC"&+5Z!&Dvs)&+5Z!&DK'&+5Z&DR*&+5Z&Dj 3&+55Z&DP $&+55Zs,:C@/  BB>;>"bY?>>>> > >>;cY H@1 H H H 4]Y+'' 'hY -]Y ??+3+_^]3?+9++++??+9/_^]_]_]r+93_^]10"&'#7##"&54632373>32!#3267%2>54&#""32654m/ JX]~3 9,\4ohBLH}IBEDxFAqX-6<^\Iڻ_KYZ1>`g.(V{P`}T\saS_Zs&FzZB!&HC#&+5ZB!&Hv-*&+5ZM!&HK(&+5ZB&Hj 4&+55%C!&C&+5%P!&v@ &+5$M!&K &+5%$&j &+55H++@%cYcY?3?+9/999+10&'77#"&546323&''2>54&#"j&Vv^LQ@蕬Z aXnBqAMFIr?N&*?MkjΥ}^)odM[jkQ[%&QR- &+5ZT!&RC&+5Zh!&RvX"&+5ZU!&RK &+5Z&RR#&+5ZT&Rj ,&+55m%T@:// I&IP`p Y`/o/]]qq+3/_^]++3/]q105!4632#"&4632#"&mJBBIJAAKJBCHJAAKdLKNIFRNKMQGFQN+f$ @!]Y]Y?+?+9910#"''7&54$327%"&2>7T{fmwH`FTBBR{Hm#IwM 15lkM8Xnik6rPnDo!&XC&+5o!&Xv&+5o!&XK&+5o&Xj )&+55s!&\v&+5h#'@ ]Y]Y?+?+99??102#"'#!!36"32>54&-≲] H-B3GvICHG{FKs̓P`|XXs&\j )&+55&$MR&+5Z&DM#$&+5}&$N\R&+5Z+&DN#&+5&$Q7Zs&DQ{7s&&vR"&+5Z+!&Fv"&+5{7s&&KR &+5Z&!&FK &+5{7f&&OR#&+5Z&FO#&+5{7s&&LR$&+5Z]!&FL$&+55+s&'L\R&+5Z&G8'%+Zq+J@+%]Y bY 0     ]Y ???+99//_^]^]993+3+1023467!7!7!3##7##"&5462>54&#"TX}- )'#-#)MUQDtLAIGzGL5EPlǡTZKõNwlHXzoXX5&(MVR&+5ZB&HM %&+55}&(NR&+5Zc+&HN$&+55I&(O-5&+5ZB&HO+&+55&(QZ(Bs&HQ5s&(L-R&+5Z!&HL,&+5{ms&*KR$&+5!&JKF3&+5{m}&*NR &+5+&JN/&+5{mf&*OR'&+5&JO#6&+5{;m&*9!&J:w1&+55s&+KR&+5%&KKN &+55-M@. lY iY I) I I I I  ?3?39/++++++9/33+33103#!!!#737!!7!7!{)Ά))(2))1V%)%w-ô%` !;@  lY]Y  ! ?3??9/]+9/3+3910)654#"!#737!!!3>32}j]+V+#-!++&*>d PD3{oǡǤ}N\Of`&,RR&+5%|&R &+5&,MR&+5%&M&+5}&,N]R&+5%S+&N&+5&,Q&LQ\f&,OsR&+5%?^ ??10)!R-^R&,-%&LM`Rs&-KUR&+5D!&7K&+55;&.9%;&N9{%^@   ?3?39910! !!!3XxJ-#),^H^5s&/vR&+5%&Ov &+55;&/9B;&O9"5&/8!?5%N&O85&/Oup  >+5%&OO!8 >+5 (@  iY?+?993333103'7!7!7g:fݒ/kkV6wN˧h !@  ??993333107!'7!/@jc'Q5R @ oY"?+??3910"'53267#!!3767!xFZGo~ ^ 5J} .RVdR;P'PuLJ%ms $@ ]Y]Y?+???+910"'53267654#"!33632#hF=5=]l\+bъ)QYD3{1^䧛Ik{&2MR&+5ZT&RM&+5{}&2NR&+5ZW+&RN&+5{s&2SBR -&+55Z!&RS` +&+55{{!]iY@2I' I I I  iY  iY iYiY?+?+?+?+9/_^]+++]++10)# $32!!!!!27&#"F]W\E)5D7#P5XF>jys'  'Zs#09@P  88414bY?4444 44411 1cY  $]Y +]Y! hY?+_^]3?+?+99?+_^]9/]_]_]r+93_^]10"&'#"&54$32632!#3267"3254&%"32654t.?{݊h3f`We]hGpEIImJX-MDDMI[i&0.(y~[b `evaS_5s&5vR&+5%!&Uv&+55;&59;s&U9&5s&5LBR!&+5%,!&UL&+5)xs&6vhR,&+5!&Vv+&+5)ds&6KR*&+5!&VKt)&+5)V&6zds&Vz/)s&6LR.&+5"!&VL-&+5;&798;oL&W9s&7LR&+5^(&W8!&+5(@iY  iY ?+3?9/3+3103#!#73!!!7}}7L77RTboL 4@cY lY @]Y?+?39/3+3+310%27#"&54?#737#?3!!3#Aao !))Ą12))#5~B.TƔJ`&8RR&+5o&XR1 &+5&8MR&+5o&XM9&+5}&8NR&+5o+&XN&+5&8PR&+]55o&XP &+55s&8S?R &&+55oR!&XS (&+55&8Qo^&XQs&:KR%&+5}!&ZK#&+5?s&<KR&+5s!&\K&+5?V&<j#R &+55s&=vjR&+5 !&]v&+5f&=OR&+5&]O&+5s&=L R&+52!&]L&+5 @ ]Y ]Y?2+?3+10"'5327>32&#"HhF=6$*ïkPE@9EM1PA/@ cY ]Y]Y?+?3+9/3+310"'5327#?>32&#"3#hF=6$)ðhPE@9F 1MqPT1PA>b)&./L@.*iYO***$O_o@0p. $$1/?3?9/333]]q]9/]+10!!!&54632%>7!#4&#"326!&'=M+on$*V:Tנ7**600*7+5C pDJB0Bny/ 1p&-33--33oj5U9Z !4BC @O H @/o/ @HC0@ 0@ H.C1.3-"))<]Y)"5]Y"?+?+99???9/+_^]9/+^]q+10>7!##"&546324&#"326"&54632373#7#'2>54&#"'&V:T;rppn7**600*7Pa'9CENM?D{ICz* 1p&kmlk-33--44}gTPG]tXXos&vR&+5Z!&vL&+5ds&vR/&+5+f!&vH-&+5);V&69;s&V97`!@  @/]q3910#&'#5>7!`?ci?4Rh25sXP9B6Hy! @    /]q29103673!.'y?csuSh2!5s^Ji6H@ /]q310!!k-{++@  U e 6 F  /]q3]]]]210!"&54733267{7IQNc+~&A<6GB @p   /]q3104632#"B_WILX\dWY>:Pc  $@w  0@x0/]]]/310#"&546324&#"326 rnon7**600*7komk-33--44T@ ?3/9]]3103327#"&5467wH ,:TPfw_x`h2kXRM;W@;Vfv7GYiy8H    /]q99//3]]]qq3]]]qq10".#"#3232673b1K@;!1;1MB:"0B!'!835!' 37!@ @/]q321067!#%67!#ru1+`ru1+`5E5E5^/]1067!#5LJxƧFV9@$_o@ H  F 7  /33]]]]33/+]9/10>7!#4632#"%4632#"IZMD<=GJy'MD<=GJy*KNP93IWnNP93IW&$T ?55)}jD"/'(T ?55"7'+T ?55"',T ?55>&2wT $?55"v'<7T ?55>;'vT *?55Gx&U .&+555$5%5iY?+?10)!!b5.6b(5(=5+{r@NiY$,I$$%H "I.INI.I$H' I I I iYiY?+?+9/_^]+++]++_q+_q+++++10!7%# $3 %"32654&5D5\_"ńs}jf!V3 18Ŏ,5.R ?2?910#!!&5{V; /*TDDqOW5051h IiY@&I' I I I  iY iY ?+?+9/_^]+++]++10!!!!!8eb755{3w=H{25@ iY?+?310)!!!d350L53 $@iY iY?+9?+910#7 7!! !+116> T5)7?<{H 9@  oY oY _     ??99//]q3+33+3107.5%7!>54&'!-1wtY%%1dvpvo tב?  Ǧm ©py;!@iY ??339/3+310#!#"&547!;!3267!\_^'eop"f)omNϸYl!D1bR!(@ iY iY ?3+3?+9310"!!.54$32!!$4&hsuGJ;5kk{Q٭m7;o˅ECgbV&,jzR &+55?V&<j#R &+55Z^&~TD 7&+55'/^&T .&+55%m^&TB &+55`^&T &+55w&U 1&+555Zs!/-@)]Y dY"]Y??+3+?+9910>73327#"'##"&546322654&#"y9-]C=$?f-Q\Y}3MtC@AGyHA^SxA _F[N^ VP`xc\+H@)$%%$]Y%:%% I % %% ]Y ]Y?+?+9/_^]+_]]+9?102#"&'!>"32654&+732654&#๧}OLrY.Sfh6qic/3;n|Jw!*cx|#~\\|DK;^@  ??39/3910!7!3>7!}3'' 2KCbjP k3t 7'7@ "]Y"^Y  cY?3+?9/93++9310&54632&#"!"&542654'pcwCP.hef~M~554&'.Z}Nf2 'ֈV\ja1WcwM8Q ߶|Lk*2ObB[\wu-"4%FB%ms@ ]Y  ????+910!654#"!33632hl\+bъyD3{1^䧛IkdT@8cYo*I#IO2I%I cY cY?+?+9/++_^]]++]q+10"&54>32'267!"!654& ?3A^a$\901=@!($%$cY//bY%11]Y_o/]?+9?9/+9+10#"!>54&'.5%5.5467+7!#";PFFlxW-WcqO;Jk`k:51-jusfgsDU4[\qz.&3"F;^rPp* @xSPTTZTsR^^%@ cY]Y?+3??+3310%27#"&546!!#?!#ABd rο/l!7yF3yR(Hhs%@ ]Y ]Y?+??+9310#"'!>32"32>54&h_ H.֝NWj"71dFsMB|R:oXpXbZs !'@]Y!!]Y_ o  /]?+9?3+10!>54&'.54$32&#"Ndja1WcqO>G \~bTOuPj-2ObB[\qz.(7 GƔKH9pZ;^@ cY ]Y?+?+310#"&54$3!!%"3254'JWσ1A/%5iRt)Nm[;-xՄof^%^ @  cY]Y?+3?+310%27#"&547!?!!Aao s1s#5}2>RJw^@  ]Y?+?310"&547!3 ! +5-PƶFP`=<}aZs#$@]Y!cY???+?3+310.547>32>54#"iߥČnTDn/̯Ω`fQ^Y(={mxҼ &݃s5@ dYdY?+3??+39933?102!327#"&'!.#"'63|@LJ 01-:ab~)5 **"'4es1:;!}NMA'w @  ]Y ?3+3??3?10%6!!.547!!wĵ-cb+[W `-1ƪFP`=54&+!!!!32uNPDIL%?F7%7l94b&'LA=6^'BL5s&av}R&+5{7@ZiY$,I$$%H "I.INI.I$Ho' I I I iY  iY?+3?+39/_^]+++_]_]++_q+_q+++_q++10"!!!27#"$32.95\zhvH˿MM+18)8)V6,V&,jzR &+55R-?$0@$iY iYiYiY?+?+?+9/+1032)# #"'532>!32654&+DJOP?5/ATPiGLw_amu?'HyuJQ5)@ iY  iY?+??39/3+310)!!!!!3232654+@m52wy1wVI}my1Eynh#@ iY   iY ?+3?39/+104&+!!!!32!67JKِ7%7l9Td 'D7^>p^25s&vR&+5&6/R&+55V @  " iY ?3+??310!!!!!!j40\\LJV$5 &@ iY  iYiY?+?+9/+102)!! 2654+dN566A%lTyujw5%5a;V $@ "iY iY ?+33?+?31036!3!!!!5y\] NoLTV^5(!@  ?33?33933310 !!! !!!/ %H'ܗ TT-13)'f@   $oYoY-$H@ I" I I I   !$ oY ?3+?39/_^]+++++_q+9+3_^]10!"&'32654&+73 54&#"'>32ŏ͋N٪3_^m{mw $+cys]WHR{[GX5@    ?3?39910 !!7'!!r^d#5AJ؏LF5&6R&+55 @ ?3?39910)!!!`52X1T-@iY iY?+?+?10 #"'532>!!#OP?5/ATPiG]u?'J505+{25n53{7&7 @  iY?2+?393310"'32>7!67!|WQu0J?13.XN  '"AQ]:n'yI{Hsy;5V @ " iY?+3??310%!!!!!h\/540`L@m@ iY ??39/+310!#"&547!327!w p1l 21V9;%.$JJ5 @ iY?+3?33103!!!!!55:};}9LLJ5V!@  iY"??+3?3310%!!!!!!!\5:};}9`LL@' &@iY iY  iY?+?+9/+1032)!!32654+CI7dlHuj5"@ iY  iY?+??39/+10)!)!3232654+5:h52w%iEM6Kuj5R @iY iY?+?9/+10)!3232654+RI52wCJdlKuj@ZiY$,I$$%H "I.INI.I$Ho' I I I iY iY?+3?+39/_^]+++_]_]++_q+_q+++_q++10%267!7!75!"'63 #"&'<5A}PyS83ZE%.`5#C@+ iY I) I I I I  iYiY?+?+??9/++++++10#"47!!!!32%"32654&Ͱ52yPe kfwjkerD'2, 4;ɋ 5iY@I I iY  ?3?+9/+++910 !.54$)!#";akY3wm^l1DkJ1roO[ZsDm&=@"  cY  m   ]YdY?+?+9/99_^]]+3104$%>32#"&%2>54#"mEiS+B_BsGs8<i2"SYykZRsOZZs *A@&$$bY$&I$I$$bY!bY?+?+9/+++_^]9102#"&54$32654&#"32654&ǻu}YZu۔[YU\apU'W_BsnrTjYCh iuVDBAnFE05s&;@!"" "&$cY$cY?3+?3+9_^]]3310632327#"&54>7>54#"гBpRdA^rFoE\Y$yrX_{T;#$*dZ/']|S6)(*VKZ&*@ !]Y ]Y]Y?+?+39/9+10#"&546323754&#"'63 267.#"yݍ`ja?j!YGsLJѺ$ε)1BWݺXcZBsHs9i@B7bY7I%I"I+I%I I9']Y"-  ]Y2?3+3?3+3??9/+++_^]+++]3+310##"'732>54&#"56323!3632&#"327#"&57#!+9M:/5THHA-LLfd!d9$GA45}HA-LIi` ށ`a/ `a-=s$d@$# # $#bY$I$ I$I$@I $ $$ ]Y cY ?3+?3+999/_^]+++++_^]9102654&#"'632!"&'53 54+7όtDVEMH|eE-;D.4-"Vg%8(#Xuo^Xo?&X6&+5%^ @  ?3?39910! !!!X!u.o^!^s+@ ]Y dY ??+?+993310)&#"#"'53267>32Ӽ(CZJH#C[`Y<%/2O&fpWEu?gNio/u93^@    ?33?399310#&'!!>7!!R*?; B-'>Oh^#TG54&'ܢ`h+ZVV]R]Q[Od٦&/ g i jr`^[jo^ $@ ]Y]Y/?+?+?39103267!327!.'##"&5473l\+b->'3`85Ɖ^sD3{Au_;ȥD\^@ ]Y  ??39/+910326?!!67##"&54?!>>9b--@ 3^D2?@/U_Oj^%'@ % !!]Y ??3+3?3393103267!#7##"'##"&547!3267c]+c-+ Յ-b\/`^sF1{㦛Ik}sD3{jo^.,@. $**]Y]Y/?+?3+3?339103267!327!&'##"'##"&547!3267c]+c-=)1aa+ Յ-b\/`^sF1{Au,㦛Ik}sD3{\^&@bY cY bY ?+?+9/+10632#"&547!732654#"cX}X1LCVgFZ^:xeFn=BYI{ NjJ^ $@bY  bY ?+?39/+?10632# 47"32654!!5bbisܘz%9J>4IY-^:yhEWfp}C5=>]Iw%^h^@bY  bY ?+?9/+10632#"&547!"32654V|-FZNBVfyeAsw}g%>AZH{s@h bY/?,I""#H I%I"I,I%I I/o    ]Y ]Y?2+?3+99_^]q9/+++_]_]++_q++q+r+_^]102#"'53267!7!754&#"'6ב쿘h4xNq!+dWQ9]9Ps7'u{[c R%Ts G@- cY# I"I"H" I   ]Y]Y?+?+??9/_^]+++++10#"&=#!!36$32"32>54Tb0]9NDnD@nB53^R y}{^#W@! !bY!ͲI!DzI!@I!"H!!cY dY?+?+?9/+++++_^]910"#"'53267>7&5463!!";9R.Bo[<(%*5:O5[O]FM];Odt-"`NAWI7CZB&Hj 4&+55%`*+E@%&'&lY'')$ ]Y   -+)$]Y?+???9/_^]+99/3+310!!3>32#"'53267654#"!#737!{++&,>d)ɣhF=5=]j\,X+#-sǻfN\OfLQYD3{oǡJ!&v/&+5Zs}@TbY,I/""#H I%I"I ,I%I I   ]Y ]Y?2+?3+999/+++_^]_]++_]++q+q+10"&54$32.#"!!3267ؗ \6hB["o+LEZH"sr/#OsV%L%$&j &+55M{s(5@@&)bY &&]Y&dY 1bY ?+?+?+9/_^]q+10632#"&547'"#"&'5326?>32"32654?ln|Z-CYGDHge3;!%/3M#+Q̝ΝEZLCVgyeIk@[ gp\:[#=BYI{1{^$P@1bY cY# I"I"H" I  bY ?+??9/_^]+++++39/+10632#"&547!!!!!"32654?tf|c/\'Z-EZLCVgye=]3^R}[#=BYI{%`%!&v&+5s?&\6&+5j^"@ ]Y0???+?39103!3267!#7##"&547T1`Lۉl\+b-҉)=YsD3{㥜D\5@ iY?+?10!!!Bu56H%5@ ]Y?+?10!!!!I@f^1s&:C%R &+5}!&ZCs&+5s&:vR'&+5}!&Zv;%&+5V&:j}R 1&+55}&Zj /&+55?s&<CR &+5s!&\CM&+5)cY/]+107!)1T1)cY/]+107!)1+1)+w&I%Iܵ$IԲ"Iϲ!I@ IIβI@ I`p 0$'H ?9/+9/]+++]+++q+++10!7!7!7!`55 1AsZ ?10'673{g[gjR ?10#6JgYj'/?/]10%#6ygXj' ?10#'7 C hg{ s  ?3210'673!'6739gab%g[gj ?3210#6!#>JgYjg/}'5tLB@ /?/]3210%#6!#>ygXj d2y'9{B  @  ??9/33310%!7!%ɘ4'"CBa1)@    ??99//33333310%%!7?7!%%NC336X38D4/wv)  /3104632#"&욣9&'1b7@- >/?oO0]]q5+5s u '5@N9@"6L@3333<""E,O?3]2???333]22310"3254#"&54632%#"32>54#"&54632"3254#"&54632?_8A^pzo{@9'H.7)H/lyj}'I.7B^oxj|``mJp]ana`d۔"4p]a`dړ!% HZ@0//]]10H9ϛgZP@0//]]10 '7Pn)1N^g3'3 ??10 #?JX& @ 32&#"!!!!!!7>7#737#7s)îq`Hc^']%+71em%'VDM_qwE!n\w9%.P@-#&iY##% cY@o .iYcY?+3?+9/_^]3+3?9/+10%267#"&547#?33#!2!#!32654&+&@+h{>o{3.B.=Ro3`^D5t/Vjs$(ԿKP)&q@G tYtY/ @H ?@ H# sY vY?+3?+39/+_^]q39/+^]3+3+310"!!!!327# #7367#73632.a8\' +%Yg~B% }'WGdV}WXՕ"Qx{??C0.91{'31@8(%%%/0 8?3???99//310"&5432&#"3267 # #"&54632"32654ʨmb7U;2M+63!=@`?ʮ}̭+E(*&?T})#PA324&#"32>/5-0 'N']scoz$&+F-J*F.ND}Jysms-32!3267.#"1RRHbٓ2XzK#5Fh)|5Bua'&{>d ?555\&u')> 6?555f'&<> +?555''>f= ?555Ls$;@" dY cY   ]Y?+?39/9_^]++9910#"&54632'.#"63227.#"sۿҏ떉T odh'Q5FsIBϪ7CsZR2(6lpb @  iY?2?+9310!!7!&u`'#*L7W`7b@ "iY?+?310!!!%7}{7T $@iY iY"?+9?+9105 5!! !{? H7Bo md%?@Y`/o/]]qq+105!mdb9?3/9/310##5!3նFl{L#(M@0#0?##@00P`o/]]q]9999//10#"'#"&5463263227&#""32654&L{=Mq}XNK]:CEiWQPZ:CH͎İPZ凇N;Jqh  /?9910 # 3 h>s>s!fg%t&IL%&IO=?@  /]q3210#"&547!3267"Ԙ ck?LXbD^  ]Y?+?10"'53267!XhF=6=\-MPZ) ?1067!#S)@{9E{;   /]10>7!#{Q!}EV39>Mm! /10!5>73mWC(;;J/J- i@JFV4#YH ;  $HY i y  /?@ $H ??9/+]q9]+q333]]_]_qqq310##7!7!3!?w !yw: <ᗗ-JL^95YIIIҲI@Ia')  0!?3q?]q9/]]+++++102#"'532654#"'!!6qڳ]3|9Yc?FLw)+$k6#NFnC {Jm@  ??3_]q910!7!{j'/J)R5'",e@G} H) ((t((6(F(f('(((( !###?2]?3]9]]]]]3]]]+]]]93102#"&5467.54632654&"654&dYAOƫxm39=5,4<+##1@^*paXi $bIi^x&#W>n,]*2?+,82(8*)K"&T #'+/37;?CGS[kt|@T %11&2}kKKvVulE==F>c\tZZQ)AA*B 2Vl>\QBBQ\>lV2 -, 48!59/333/3339//////////333333333333333333310!#%5!#533!5353!5!!5!5!#3#35!#35!35!#35#3#3#"&546323254#"%32+32654&+32654#"'53253T/0momImmmm0oowoooomm~smp.,;0m^{B.$*/;J1%Z^4+V}i0oo/mmmmmmoo;mmJoooo/yhIaCS1@ D8QYb" "+%J fVr_cT*@(""//39////310 5467>54&#"63232654&#"TV'FdLOGRZ?>1HR=GFBIHCHEVW//=8NZ8*P:/5K6CpK;?HI>@IH!&7L&+5jRu 8B@%]Y **]Y6 11cY1']Y?+?+99//_^]3+3+10654&#" #"&547>54#"563232.546323|H?BA6 9&2tmkj#|z;|1Vb27u|XA]2:-jTJqS*f lp##H!@  oY?+??933107632&#" !!qCфSO8&;@uw8f{PN/^^+1@##   cY )]Y?2+3?+339/910"&547!?!##"&'4'!326?!32)YIi/lBpESdrӾiRXoaim]I0۬oU2s+5u&0vT&+5%!&Pv/&+5&$X^Zs&DXB; ??10#nWJ F@0[k0  &    @Wg0/I,I?++q]]]]_]]10#"&546324&#"326rppn7**600*7kmlk-33--44X,(@ ^Y ]Y)]Y?+?+9/9+10.#"3>32#"&54>3&#"3265v?9%h2?JPNA32&#"!7>32&#"3#!"'5327!!!4632#"-hF=6=\̣)ðhPE@9F )ðhOEA9E 1MhF=6$tM-`WILX\PZőTT1PA>T1PA>^WY>:Pc%;8<G@%;:* 66cY'  #]Y2]Y-?2+3?3+333?33+33??10"'53267#?>32&#"!7>32&#"3#!"'5327!!!-hF=6=\̣)ðhPE@9F )ðhOEA9E 1MhF=6$tMI-PZőTT1PA>T1PA>{#4@    iY@ H iY?+?++99_^]310# $3 67!%"32654&\2p / /ysyypA' J:Tͷ>ƎZ"$@ ]Y]Y?+?+93102>7!#"&54$4#"32>sDT' 0.KwKKxCs<3NMEz}{`@   iY ?+?39/310>7!!"&547!3267'LT/ 7!#7##"&5473l\+b-3D+/ :̮҉^sD3{p >aj㥜D\!C!vRERA@ (  H 8 H8)@ H/9/]+9]]++q10#7>54&#"5632NA 3JIezAZH{5j$R@2"iYiY I) I I I I iY?+3??9/+++++3+3?+310"!!3267#"7#!!3!2&75|JƆ52yR zhv˲#3 -M+ V;18a%s%t@H# ]Y I Y # I I,  I w f  I     ]Y$?2+??9/_^]+_]]_]+_q++3++3?3+9910"&547#!!36$32.#"!!3267b0]B#µ\5hBP'g0]Q={[& 1^RH#mb`a#/O !@ oY ?33?39/+310)#!!!#7&'/)uD15|wDw~{;^ )@bY H   ?33?9/9++310!#!#!&'9%Pa) ^ZZ^e5-@  iY  ?333?9/3/+33?310!#!#!!!!!!3&'D1/Z5)x^?u*wwwCDdڗc%H^0@  cY   ?333??9/+333910#!#!!!!!!!'Vhc\\jZt333^R1@iYmY ?22?9/3+3+99910#>77!!.+!#" !VDHyq !/.}ʃ7W(Fkى$D`T{O_3qC^T@0HB bYaY P`?22?9/]3+3+939_^]+10#>77!#.'!7!f=zPR%! \g/8źs}mhh3I@=885 %B@# lY iY  iY  ?333??+999/99/++310 !67!!!!7!!.+!#"7m2;52yG^]2 !./}˃ 9P)qCLo?&[xD`T{M]/%^"f @=H  B     " "bYaY Y_ o  P` ?333??9/]9/]++3+999_^]+10!67!!!!7!#.'!7!+2c\SP%#]g/8ĻLX)3^RFhh 3HA=88/Ki@:     +*+*oY!#++M= =7;;FA7@I4771oY7nY"?+?+3329/9_^]9/99+999_^]]]]10327632.#"&54>7>54&+73 54&#"'>7&'53>32&#"řÃ^)wGXW7zJ8`yB3_^mVn2fk/P`b:<*"&%_Qw ")J)vY!:TF[SHR{7Mhp>YK' CW!/)dL@a9)I))))++:+J++ )+=#LKLKbYBD BD0 LLN =0bY=Vf    bY ?3+_^]29/3^]9]/+9/999_^]]+999_^]_]]]]102654&#"'67&'53>32&#"32632.#"#"&5467>54&+7ՍmDVEMHu)Tk/Q_e7>(%#$N>ytpUG>EADBL4V]ߌs4XX-;D.4-"4P{p>ZI' 1>?f& 8tX -++! #;24:uw{ ]@>iY"III"H I) I I I  iY iY?+?+9/_^]+++++++_q++10# $32267!"!74&\4{1x=yA' Cɴ8۷3ZTs |@R  bY'#I""I I-,I%IIM)I  ]Y ]Y?+?+9/_^]+_]_]+++q+++_qq_q+_^]10#"&54$32267!"!54&TM|"{PK{$LMT|r[b{ndi@  iY?+??910>7>32&#"!!J\v_RF4-@Z3'31:"῕HZcIYff@  ]Y?+??91067>32&#"!! 32%"'632654&'ϣ BA32>l6<a\V+TTTe^8*MWe'e70#i%LL 5RN1ᇗ4 ?)&Zp@?74QQ:A'HAHoY$-AUN:NiY4:$#$ lY 0 @  p   @lY?+_^]q9/+_^]?3+3?39/+39/910#".#"#>3235>54&'.54632"'632#"&'#"$32'&#"32673265)3GzhX'+3>wux@H??>GV3X3i޴}>Vi:a4$DHcjW[)OmDvm"("3;&-&p \1* "-2Q)#i8NKVC(;,0pqXW2XZTR,@Ri@8DDP&/@bY//884@4;bY4@%H4@P &  ! cY cY?3+3?+39/93++_^]9/+9/10"'#"&54632&#"32673254&#"'632#".#"#>3235>54&'.5432'iɐfVvvw@I?}HVnnU>)z݌?Nl`)>"("4;&-&w\0* "^RA&i hZA&+5f&j h"&+5{7@iY iY  #??+?+310"327!&5$32.}nf\zhvH˦$& 18)8Zs@ ]Y ]Y??+?3+10!.54$32.#"327fk\6hBUMdi֭[H"߀-hy  ?/10%'%7%7%LG㴁FGJ{J;{Z}9IĤ{-{H@   W/]q2/]10#"&5463!632# "Y02H?Y30H=^;-54&'.5432IK}GV\0* "^R) (6DR_m@iP4H, B&:V^&,c4k no-&44)"00)d^Wkk`ZggS`IB;PPE>LL7E)`EE`)P     ?o/]2q2/]]3q29///333q2333q2333q29333333102#.#"#62#.#"#>2#.#"#>!2#.#"#>2#.#"#>!2#.#"#>2#.#"#6!2#.#"#>]qO?#&*-O;_;;;;6@3P3333.6-&..&-6  ?/9////////]]93310#67'>737&'.'5467'67".'7&'7 F$a5; Ia4#GA݁hBO݁E?軋Ek(8PC{Lh&ZC7#BO݁GA܂ Ia5; F$a5[8D.^3DuOW.FcB=FK5VH$2@ iY  "$_@!0?2]2??+99?10!3!!!#7'!#"&547!3267jA r1^d#"Ԙ dlLFTL؏L/[_jo?+-@+#@(0 @cY?+??392/10!7##"&547!3267!3!#"&547!3267Ɖ-l\+b-i2 ckȥD\sD3{?¤Xb5R9@ iYiY   iY?+?99//_^]3+3+10)#737!3#3232654+RI7 2!8!CJdl!Kujs%&6@bYbY & !bY ?+??9/+9/3+310!!632#"&547#737!"32654m/)eX})/-JFZLCVf5)xeFn N=BZH{5*@ iY iYP   ??9/]++910'+!!237'7654&+솁8B[cm5554#"'7RiW3> r: HV p;JW[SWHs^}ZmRF]JA׈uK_R $@iY  iY ?+?9/3+310!!!#73!!58}7.6RTd^ $@ ]Y  ]Y ?+?9/3+310!!!!#735I/1XZ1b^^5+@iY# iY iY??+9/+?3+10"!!!632#"'3254&VI6u5.6VPXsؾzȑ/ g13 ӥ% ^+@]Y]Y dY?3+??+9/+10%#"'32654&#"!!!632ՒR`}YW/#P5I53Pʸ+6ؼqz^V.@"  oY?+?3?33933?10!!! !!!3!;ܗk/ %Hя\13 TT-`os9?@!7bY91']Y"-  ]Y2?3+3?3+3?/?9/3+310##"'732>54&#"56323!3632&#"327!.=#!+9M:/5THHA-LLfd!d9$GA45}NERP\` ށ`a/ `a!o֯-=)&|s&|q5V"@  oY"??+??3910%!!#!!!#]52X`1T-%o^!@   dY/?+??3910!3!#!!X!`u.o^u!^5#@    ?3?9993910)#!!73!`{Vyo52KXNTTf/Z^#@  ?3?9993910)!737!!#'-oVDP"}#N/^d@( iY I ) I  I  I I   "oY?+???39/++++++10%!!!!!!!!\)52yy1`w=%o^E@*  cY# I"I"H" I   dY ?+??39/_^]+++++10!!3!!!!D]]Z-^`b^Ru3^5 =@' iY I ) I  I  I I   iY ?+?3?9/++++++10!!!!!!mΆ)52yyf5Lw=%!^ A@) cY# I"I"H" I    cY?+?3?9/_^]+++++10!!!!!!D]]Z1`b^R3^5-@iYiY iY #?3+?3?+9/+10632#"'3254&#"!!!!I_tۿ{ɑM2uE513 ԣ L% L^-@]YcY dY ?3+?3?+9/+10632#"'32654&#"!!!j3PʒVb|[V.#PӺ^+6ؼryy^{*4L@-+0"(0nY((`(p(( ((iY ""iY oY ?++9?3+9/_^]+910327#"'#"$32&#"&54632654#"2?Ld2q`{ZsTQUz|?q΃+Tm>E_m  ` $-xL}fޯbZs*6+H+@ H+1(1bYP(P(`(p((((H( H(@ I( ((]Y ""cY bY ?++9?3+9/_^]+++qr+9++10327#"'#"&54$32&#".54632>54&#"yZ">8FUk`}ؙ32327!&547654#"!654#"!336L+Di;=)1`@b^(`Ӊb\+bsnvJhAu1>A/D3{/D3{1^?<f^ @   ??33?31067!!!,,)Chi'05XR^PaL?5@! iY? O    ??39/]39+310 !!!!!!7!svV'5:958fPy^!@  cY  ??3+3?391067!!!!!7!!(4)C1781'-1wdR^9Vy"@"  oY?+??39?10!!!!!!t@@kX߲\+`o^#@   dY  ?3/?+9?10!!!!#!{Asb- ^}=!NuVVo&@ iY iY iY"??++?3+310!!!!!!!B\/750 LNT\o1^$.@!"!cY "]Y]Y/?+?+?39+3103267!327!.'##"&547#7!Xfa+b->'3`85ƉP11yXD9uAu_;ȡZyV$@"iY oY?+?39/+?10!#"&547!327!!!w p1l 2\1V9;%.$J@`o^+@ ]Y dY?+?9/+39/10!?##"&54?!326?!3!@ 3->>9b--`/X\OD2?@um@iY ??39/3+310)#"&547!367!7wfLFA p1l }EDR^21./9;%.$v H,^%@ ]Y ??39/+9991073>?!!67##7"&54?!>H1/E\#-? $>I6/3^D2^#ß/-D$ըO5@ iY ??39/9+10!632!654#"!j2w pm V5@.$Jq%!^@ ]Y  ?3?9/9+10)654&#"!!3632=>9b--?#F1?@^ZZD=;#-1@ ' oY''iY$iY?+?+39/3+310!2!#327# 7.54733"32654&Xv~jűJ5--׀0\Ed'BƳKM&VqubQ='/gɞvr;Ds#,M@,'bY ?'''' ' ''$cY"cY?+3?+9/_^]_]_]r3+310"&57$5473;632!#3267"32654:+)! <=ٱ3g`We6X-)dR@G*.[i&0VsaS_=V;&0C@#" $$*oY *'** iY 'iY ?+?+39/_^]3+39?10473;!2!#327!&57."32654&=J5-- ^~ v~jņV^B0\EqubQ='/,=ƳK= f2Vɞvr;Dos&/S@/%*bY ?**** * **#%%cY%'cY/?+?+39/_^]_]_]r3+3910.=$5473;632!#3267"32654\:+)! <=ٱ3g`WePX-o'ҡ)dR@G*.[i&0C+saS_,&6`R&+5?&6y>&+55(@iY# nY ??39/+3?3+10"!!!#"'325sSMm52XvbĨ{z!TR13 B% ^4@bYO dY ?3+??39/_^]3+10!#"'32654&#"!!X-]b{|oF;N-n^۷դ+6ȵt^V$@iY iY iY"??+?+?+10 !!!! #"'532>1OP?5/ATPiGTLu?'os!#@]YdYcY/?+?+?+10%3!#&#"#"'53267>32 (CZJH#C[`Y<%/2O&fpWEu?gNio/u95=@' iY I) I I I I   pY#?2+??39/++++++10"'3267!!!!!{}'k)52yy1=12=% ^A@)cY# I"I"H" I  dY ?3+??39/_^]+++++10!!#"'3267!!D]]Z-5ԛgrobx"Xb^R:<3^5V>@(iY I) I I I I " iY?+???39/++++++10!!!!!!!!=)52yy11w=TL%o ^C@)cY# I"I"H" I   cY?+??39/_^]+++++/10!!!!!!3!`b0]]Z-3^RVm"@iY "oY?+??39/+10!!!#"&547!327![єD p1l 2V;V9;%.$JJo^A@' ]Y*I1I" I  dY ?+/?39/+_^]+++910326?!!!37>7##"&54?!>>9b--T  <[3^D2?@o7-uBKO5VH'@  iY" ?3?3??+99310!#!!3!!!#67#j=+#5A %1+B mҗXETLou^%@    cY?+?3?3993/10!#&'!!67!3!#R*?; @I'>Oh^#TG,^&$6uR&+5Z?&D6%&+5V&$jqR "&+55Z&Dj 3&+55oZs5&(6'R&+5Z?&H6&&+5D";@"oY & I  iY iY?+3?+9/+_^]]+10"63 #"&54$!3654&267#"mS "k@N, NFĴ)%wnX- 嵱M63g`WegŝuaS^)[i&01%DV&j}R 5&+553&j 4&+55V&jqR $&+55&j L&+55)V&j-R :&+55&j 7&+550@iYlY oY?3+?9/+3+910!"'32654&+7!!KJ-{17Z+LO*9taY\-^3@aY  dY ]Y?+9?3+9/+310!7!#"'32654&+71V)śעFO|-u?͠P (6iu5&M R&+5o&XM3&+55V&jR "&+55o&Xj )&+55{V&2jR .&+55ZT&Rj ,&+55{{ZTs|{V&{jR 1&+55ZT&|j 1&+55V&jR /&+55&jO 0&+55&MmR&+5s&\M&+5V&j1R )&+55s&\j )&+55s&SR (&+55s!&\S (&+55mV&jR '&+55&j ,&+555V @"iYoY?+?+?103!!!!55.6\>`%o^ @ ]YdY?+?+/103!!3!%3I`^u5V&jRR )&+55jJ&j 3&+55&}@  0ִ>+]q5^7@ Y ]Y dY ]Y?+?+?+9/3+310"'5326?!#73!!!!!hH7K4Ʈ1#9;fqɋ}KHZ#1,@  +]Y $$]Y ?3+3?+99?/10%#"&5463234>!326?!#"&'%2>54&#")Ϻ努` S- @3KN51C-߽s,IwFCIExKLȾhK[2$8=cVTI|P`XXq,1@mY(**%oY* iY/?+?+39/+9103267!#"&54654&+732654&#"'6!2DntzBPT6c, ml/QOrs) n}t`w-&M-OUws?NiӐs+j@(bY`pIIϲ I@ I,"/ "cY " ]Y /?+?3+3_^]9/++++_]+9103267!#"&=4&+732654&#"'632A2IM=1C+Ͻ\}-pIQFJH{J65ZiŢ)OD:E6,.!Vj$ V%3@$"oY oY!oY?+?+39/+9?10!654+73 54&#"'>32!!DO4~^^m{mň \m?-HR{[GX` wO`os$^@bYIIϲ I@ IcY# dY?+?+39/++++_^]+910!7654&+732654&#"'6323!L7^^-}tDVEMH{`DH;;D.4-"Vj# 3%Xud&#@&iY&iY iY /?+3+?+103267!#"&547! #"'532><;ETT5b+OP?5/ATPiG<"3?fq-ñ>qu?'s/1@&$$"*]Y*"dY ]Y /?3++?+993310326?!#"&547&#"#"'53267>32+@3KN51C- b(CZJH#C[`Y<%/2O&fpWE T8=c¯6;?gNio/u9q25o=@'iY I) I I I IiY /?+??39/++++++103267!#"&5467!!!!<;ETT6c+!)52yy<"3?fq-ô-k=%^A@)cY# I"I"H" I  dY/?+??39/_^]+++++10!!326?!#"&546?!!D]]Z- C6CQ51C- b^RV4&68`w®8#3^{/@iY*I iY iY?+?3+9/+3+10!! $32.#"!267!#DseJ!50c6"ʷZs:@"YII ]Y ]Y?+?3+9/_^]+++10!!"&54$32&#"3267!7 82mDmh[iG2&Halkj9@ iYiY?+3/?+10!!3267!#"&54777<;ERT5b+<"3?fq-ñ>q^^@cY ]Y /?+?+310326?!#"&547!7!!b@3KN52D+T/1` T8=cñEt17D']@" oY-  $H @%I " I  I I   iYiY?2+?+39/_^]+++++_q+9102.#";#"3267!"$54675&54$#~Afjz3{ˉ{]O,>P/@^N[Sur\N5+VȲ H'/s +@ iY iYgY oY?+?+?+?+10!#"'5326?!! #"'5326+X'iH732'M'hH73232673767!#&'#%A6=)%" yQ>q,-#%5 A<>$^,x) /#yx1 '-<MRz<`) C@+vWg@ H@p/]q]2+3]]]9/]10 33273673#3єTVB"?eG}RYQ? 0C@+vWg @ H@p   /]q]2+3]]]9/]10&'53%#"&53327B~58"џTVBsbjiNYQ @"H"H@" H`p_o@ H V  @/H  f v W  P`0@p/]q]]qr23]]]q+r9/+]]9/++9]+]10#"&53327'#7>54#"5632;"џTVB5CD h 63-* *3232673#"&'.D"̛R_Xl#>uQ5T28%#' 5)>5%0?B8I{Lpm.(F /?310254&'3#"'5Jm1-\=:f5a9vr|`/ @  gYoY?2++10"'53267!hH732"32>54&bR:)#-##)&GK>JxNJACzKAǡǏTQDγ~zuP`uPKf#+g@?$#$#oY)$$$"I$$$$ I$ I$ I $ $$+iYiY?+?+399//_^]+++]_]+_q_q+9102)#"#&546332654+732654+觙dw4DS iu3yx n[F1JtgbZ5%#-@ ]Y cY]Y?+??+?+9910"'##!!3>32"32>54&bR:JX1,4HN>JxNJACzKA؎SBγ~zuP`uQJ}@ iY  iY?+?9/+10!"&547!3232654&+ 1v^]r+ë18KCuYO }^!!@]Y ]Y?+??+910#"&547!3>32"32>54^-M) 32&#"&Ӏ\k^(GD45-;KˢĴMM+>KgZ#%@ ]Y ]Y"]Y?+3?+?+10"&54$327>32&#"&#"3267ו(4*K=07aTnUM[QLE[ Ts}J߀`a/#O%+f %@ iYiY?+?+39/10#!#"#&5463! 2654&+ >4DS '۔|rc[F1h'H? &@iY iY iY ?+?+9/+104!3!!!"&#";?V'e?5]EiaY1JwfUWZ$.@cY ]Y]Y?+?+99?+?10"&5463234>7!7!#7#72>54&#"꒪X #1RG!FvOHFEyHSď JcWNuHSz'N@."o ]Yt`" "  cY?3+?99_^]]_]+99_^]910#"'732654.'&5!2">54&ї߹wCP1c<hggNmpf@915Q=buO,ՂU]` IiY@&I' I I I  iY iY ?+?+9/_^]+++]++10!!7!!7!!/P5D51yAJD)']@  oY-  $H @%I " I  I I   oYoY?2+?+39/_^]+++++_q+9102&# ;#"327# $54675.546$hu3띌d艘MQwYStu^Y^.(ͺr}h3&@ iY  iY oY#?+?+9/+10"'53267!!!!+\F160D O.6O8'+=>3;Ť{V(J@) oY  (iY   iY $iY?+?+9/_^]+_^]+_^]10!# $!2>32&#".#"327!3ZX(GD44-<L`X񉑖L^B5.!& >K/4ͱ+{:@! H   H kY#?+?39+399_^]+10!#"&5467!672654';@C2q[)f CB-15H@LJmYJ+wiWVRF5C%5)'@""]Y" ]Y ??+???+9103267!#"&54?654#"!!3632%Vd#}+8%j\(hJ-D!-z -mX<_F3y޸Ê1CFf oY?+?10%267#"&547!=?o1 5}4i+;H@b  iY iY 6'I&%I"$I.III/I#I7IL I I iY?+3?9/_^]++_]+_]_]++_q+++q+++33+_^]+3103'7!3#!?#sJ%%J7J%y$JZZRRRRZ5@iY?3?993?+10)!!?>32&#"u}m52jtvHCB/1KKPF>e1Z%#@ ]Y ??399?+10! !!>32&#"3XxJ$[>24-B J % ^Hð:;9v, !@cY/ ??9/]3+3103#!#73!1Ӆ1-\w7%@@ %dY@ dY ?+23993399?+?910''7&#"'6327327#"&/&'!/?,9$Wi)-f31 #Iusy 2 %599% id11sW I0}<5y%'@ ##iY ??3+3?339310!3267!#5##"'##"&547!321 f,/EiN ♵1 K/6.PJXX@;/80T3@ oY #??+?39910)##"'53267!367! (VL160D OeT#!R;֑Ϳ=>3ߢ%ms{{j3"0(@# #iY *iY?+?399+3?10# $32>32!654&#"%"32654&]Bpn ZRB|+ysyyoD' bWhQ˦3\3,&PV9*Y;ƎZs+,@]Y  "]Y (]Y?+?+993+?10#"&54$32>32!654#"4#"32>TsOk`TяKwKKxCMOKDXyD!H1Nz}{f,@iYiYP??99//]++310!#!#"#&5463!232654+֜l4DS |Ï [F1%uh#+,@]Y %]Y]Y?+?+99??+102#"'#!>32&#"36"32>54&-≲] Hk$[>24_,GvICHG{FKsfTP`|XX53-@ iYiY`??99//]++9/10!!32!'32654+L52+5列BNJdǜ61su)H**@%( iY iY ?3+?399+99104&#"'>323267#"&54>7>!SK;uV~kWBoO-^XQ[G|[4P9@"29.̥wI.7E0EL"<\ʰy;/8Hs$,@ cYcY?3+?3+9933104#"'632327#"&5467>}\EKĸEme+fc֪kg,HI3Zaa5&/-$`V.!?#/0p+'M@1 "_Y "0""""""@"P"" ""( `Y ]Y?+3?+9/_^]q+910"&547#"&54632327";654&h umLdv"431'&86yk|w9<V#4c-+%)T $^oL",@cY@]Y cY?+?+?3+310%27#"'532?#"&547#?3!!PV&QF-;n sĄ12s#fx~2>TJf-@ iY?+3?9/10)#"#&5463!!GP 7UH1^}".@ cY]Y]Y?+?3+?39+310%27#"&547#?>32&#"!!Aao s)jNEH;B 2s#5~2>Li!;54&'!!# 547!!qjJQ;b5hs7;}NChbWD@ iY?3??+10)!>7>54&#"5632#d m58)6&Pd~9QKQ7&VWr"" #yQ!@  iY?+??933102!!.#"5>PsXwVwwu#)&&(dz|Py-NU$ ss!#@!]Y dY?+?+??910?67>32&#"!"'5326?!)+HpOS+# 8W8=Z9D0T6'8 3 :{T)y \i `e1^i@l  iY  iY6'I&%I"$I.III/I#I7IL I I iY?+9?9/_^]++_]+_]_]++q_q+++_q_q+++3+_^]3+910!!!3!!!7#I5)7T5+&2Rdf^g@A  ]Y lY #I "II I*I#I I ]Y?+9?9/++++++_^]+3+_^]3+910)7#7!7!7!3!!#+s3+͙+#=G@)iYlY  oY ?+3?9/_^]q+2+910#"3267#"$54$%7!!lˇbk$)53qrYd..Qݺ ^<@ ]YcY  ]Y ?+3?9/_^]+9+910#"327#".54%7!!?jsrp@+o36gxX/#r҅#+^$Z@ # @& HcY  Y  ]Y?+9?39/9_^]+9+3+_^]9104&+7!7!327#"&5%>+?P4=+|iQYxţw96)y^ ,&PP#-?(DoB@$ lY  I   iYiY?+9?+39/_^]+3+310 !!7!7!654#"'>323%uC5)++뮗BfSE+{ ǢCUnaȯ^A<iYѲ I@ IiY oY ?3+?+39/+++102!"&'32654&+#!!dz+]q5f;@ lY lY#??99//3+33+39/10%!5!5!5!3!!!!#<<==V5 s&''=jLuR@ !!!>(&+5+55 !&'']jL@ !!!!>(&+5+5Z!&G']LP@ 1 11)*>7&+5+55R&/-%5&/M%%&OM`5R&1- 5&1M %d&QM&$L}m&+5Z!&DL+&+5&,Lxm&+5%!&L&+5{&2Lm&&+5Z!&RL$&+5&8Lm&+5o!&XL!&+5)&8 LR!@ >))&+]555+555o&X L#@ " >+&+555+555^&8R!@##( >11&+]555+555o &X@%"%* >3&+555+555`&8 KR!@ >))&+]555+555o&X K?@!" >+&+555+555^&8R!@##( >11&+]555+555o &X@%"%* >3&+555+5553s)&$ L}R!@>$$&+]555+555Z&D L@'', >5&+555+555)&$ ON@>&+55+55Z&D N+@!y!' >)&+55+55o&M5R&+5Z&M^G&+5{m$@i"" I" #"lYM#;###  Y"III ^IYIO_ I I  iY oY ?+?3+9/_^]++]++]_q++++_^]39/qq3+_^]+310!!3## $!2.#"!2?#7373L)9sJW/NP)q.!& c(0ͱTs%3w@G?-_Y &hY$@ H!4!-]Y!bY??+?+9/+99_^]+99/_^]r3+_^]_]]31033##"&'5327#7!76?##"&5463232>54&#" ?h[xJ! zZ@CuNJ?F|IL^)V]L'D9PE_NroHXqPO{ms&*LR(&+5!&JL7&+55s&.LR&+5%&NL^{&+5{&2Q'ZTs&RQ{&2'MRQ'&+5ZT&R&MQ&+5s&L R$&+5S!&L%&+55 &'=V5 1&']jZ&G]{ms&*v-R&&+5!&Jv55&+55>@(iY I) I I I I oY ??+??39/++++++103267!#"&54?!!!!!]j/;%>52yy1hh﷧B;=%; @pYiY#???+3/+10!33>32"6$54& Z\Tk/l PraXW93XZ5s&1C}R&+5%m!&QC&+5s&$sR !&+55Z!&Ds 2&+55}&$R&+5Z+&DH/&+55s&(sR &+55ZB!&Hs{ 3&+555}&(jR&+5ZF+&HD0&+5s&,sR &+55!&sw &+55}&,R&+5%)+&'&+5{s&2s3R -&+55ZT!&Rss +&+55{}&2R*&+5ZT+&R1(&+55s&5sR (&+55%!&Us% !&+555}&5{R%&+5%+&U&+5s&8s=R &&+55o!&Xs (&+55}&8R#&+5o+&XP%&+5)s(KcYֲ I@ I %##]Y#]Y?+3?+39/_^]+++9102654&+732654&#"'>32#"'Ǫ}1jcBRGx㈵{Lqf|~DE%#4-[ #zP,45s&+LR&+5%&KLL{$&+55@ iY  #????+910!654#"!!3>32T/-5q{F9)tد?[ZEN*1@ iY %iY/+?39/_^]+9310! $5%&5467!3 7!"32654&c^u*- ~t32"32>542654#"ɖt׋\ B/N2 54&Ztֈ[ LX, FHV7S{;ABEuQTtABvOBežͣ}kR6>1IB~vLiX`fE@@32nύ[K>_bs^h CU,6F7Ds @  ]Y??3+98310!>54&#"'>32%D[Km:bjcDMΆCUDJ3'@` lY''' 'oY)"IZIRI$ I I I  iY iY?+?+9/_^]+++_]+++_q_q+_^]999/_]3+_^]3102)#7332654+3#32654+ꦙdwJ)yy)u n\a[k\tg *@iYiY?+?39/33+33103##"&54?#73!!26?!q5#<6p1pp{ )'HB:8Ri5fa@ iYiY@'I' I I I  @iY?+??39/_^]+++]+3+39+310)#7#!733#3#!3#7#fcFF58++66t7_wǮm9^^wAZVB!&,W@0)+hY +!+bY%$?!! ! !!$cY "??+?39/_^]_]_r999+99+910.54$733267#'7%4'67#Ńp~xyGWe7yH8Wu1Duh)<V,ƜD jr&0Vh1"~R=1:*R$@ iY  iY"?+?9/3+310"'53267#73!3#^]XLc{o717y4Ry \-@fY bY ]Y?+?9/3+3?+10"'5327#73!3#4632#"ZhF=5$t+`.a+}MX_WILX\#@PWY>:Pc{"0,@oY#  *iY#iY?+?+99??+10"53237!327#"&547#26765#"#Nq?F,&>3!r0A`3#}w| \k(( ;7mWWZs"0,@]Y  *]Y#]Y?+?+99??+10".54632373327#"&54767#72>54&#"XMV:9 R81Kp ")H=FuMKAD{II_gKYB0 H|44^LwP`tXX>@ iY@I IiY?3?+9/+++33910!#73!2!'32654&+ww6gBN_fJ11Ş71ruRRs+@ bY  eY?+?9?9/3+3102&#"3#!#73336J;%B-7P3)``(b s ^k9^?:@ H  lY   ??39339/33+33+10!7!3#!#73'!7#TzVi+ww+e48}/s^ /@ bY]Y?3?+?39/33+33103!3!3#!"'5326?#>7#/i2'#Gi)pZ9D0T6V2- JJ `e1N3]ibws'7@ `YcY$$cY?+3?+3?9/_^]+103>32327#"&5467>54&#" Nk H rD9`^ZR1"lPd:be17rmZsD%hs '@   ]Y]Y?+?+99??102#"'##33>"32>54&-R: BL|JL?CzKCsؾУ^^aI[uXX%h#)-@]Y ]Y $]Y?+??+?+9910"'##>32&#"3>32"32>54bR:$[>24_,NL>JxNJACzKðfTbHؾuP`us@ ]Y ]Y?+3?3+102#"'732>54&#"5>ٖ򬷐\5hBUL[Q=z\HsG#~`a#/%+s *4@!aY ]Y %cY ?+2?+39/9+10">32#"''67&54$32."32654&v A^|iy_7K@+\6hi}z*Rb5554&#"Rw5L- R81Kp ")O@FuMKAD{IIeJZnUf0 H|44bHwP`tXXZ#).@]Y $]Y]Y?+?+99?+?10"&546323>32&#"#7#72>54&#"Rw5[z]>22eG!FvOKAD{IeJZtwHWNuP`t3s #R@3bY?   cY  hY ?3+_^]?+_^]9/]_]_]r+10";754&"&'53267#"$546328Gsz:[xLT[u4F=AOk}R&+.$xu3s3s&/@P.. H.'*  bY*bY0***1*A*****'' 'cY$    hY?+_^]3?+_^]9/]_]_]]r3+392/+39+31027327#"&'#"&54>%54&#"5>267V,.;>Nx~aw5e[Rgf4TCsƱ7h^P-Tq~gjBZh$22$R^EX'/ssjs.m@  .-.-bYbY.I. I.I.@I . .." &("(]Y%" cY ?3+?3+999/_^]++++3/++999102654&#"'63 7327#"&'!"&'53254+7tFM}H"K}+/8AMvPxBp_H-;D3/OV!i^P-TOSI7&%XuZs'@U '& & '&bY''''''#I'""I' I-'',I'%I'I'M'')I' ''cYcY?+?+9/_^]+_]_]+++q+++_qq_q+_^]910!2#"&2654&#"32654&+7Z]0{-slL?hQed_pc`/-E{} &@A19}ތhqMD7:{^$@ bY  ]Y?+?9/3+310"'5327#73!3#ZhF=5$t+`.a+}M#@#'55@"]Y /]Y(]Y]Y?2+?+?+99?+10"&'32767##"&546323>32&#"2>54&#"h[3 ,HSXy;\z[A50g4XFwIJ?G}GL)V3^LֿhCaru+ˉzP`yXXs,/@&]Y]Y ]Y??3+?+?+99103#"&'32>7##"&5463232>54&#"4h[h8HSZ@DtNJ?G}GL^)V_a^LֿbE_}P`yXXZmsA@&bYI   ]Y ]Y?+?3+9/_^]_]+_]+10!#"&54$32.#"32?#`w4ˠ_<|Pjcjm1L'yXLP&qԊcn5^!@  aY ?3?+99104>7!367!#"&%2654'5,Ra X%DB/q *56GBr:o}unc4jRLZH5 !Rs(2>@"..+.. .# #]Y#)aY?+?3+39_^]]9931067>32&#"#"&54>7'.#"56322654'VAK{JC4.LG2q"?Kh#@( (RENm]?b&0#kRTF /Pv}m32&#"3>32Ӊl\+b$[>24,? 2>dD3{1ð00gM]Ik%m#,+@ $$ ]Y$]Y]Y?+??+?+910"'53267654#"!>32&#"3>32#hF=5=]l\+b$[>24,? 2>d)QYD3{1ð00gM]Ik F@.fYbY"H I*I#I I ??9/+++++q3+3?+103#!#73!4632#"ߜ+dd+^-_WILX\)WY>:Pc`^^ @  ]Y ]Y?+3?+310'7!!?!!uVVtVV]@>jIY(8  e F V ' 7    ??9/3/3]]]]]]2]]]]]2/10"#>32!3273#"'!&H u-D& qӗk!m#R0@  _Y@_Y??9/3+3+9103#!#"&54632!";654&!'wu7>t-N2&1 &Vn_r%"eH3 "&]Y?+?10327#"&547!1R81!q-_- HJGl4%8@aY dY ]Y?+9?3+?9/+3?10!#"'32654&+7!!!=V)ÚդLKz-J-^?ќP +3jtj^j^('@%"]Y?3+3?3393?10%#"&'##"&547!3267!3267!!>7+m Յ-b\/`-c]+c-/4:vm㦛Ik}sD3{sF1{%s//@+-- *]Y%%]Y?2+3?+?393?1023>32#"'5327654#"!654#"!336L+Fh)ʣhF=6$b^(`Ӊb\+b sptLhD3{/D3{1^#ms $@]Y ]Y ??+??+910)654#"#"'5326733632Ӊl\+}'WK.80E  ΊD3{@;䧛Ik%ms#$@]Y]Y?+???+910327#"&547654#"!33632R71Ksl\+b Ί HFOD3{1^䧛Ik#4%9^ @  ?3?39910!!!79%]V"_^wG^ KZTs|Zs#k@C? Y .I %I III IcY  ]Y  ]YcY?+?+?+99?+9/+++++++_^]10)7#"&54$327!!!!!4#"32>NX [  2%+/C1HKwKLxB$NN9z}{Fs,+@&&]Y""]Y?3+3?+9/910"&'##"&54$32'2654&#"326?! sDp~c{ǰ{NZ)3 0emqaͶa횚sG65Z;^@  eY?+3??10"'3267!#7#?"B);v#j-  #@  eY?+3??10"'3267!#7#?"B);v#+  #;^@]Y eY?+3??+10"'3267!327#"&54>7#?"B);v#j- R71Ko,$ #B4H|=ss@   eY?+??9102&#"!336J;%B-7t%V s  Js"@ ]YeY?+?+?9102&#"327#"&547336J;%B-7t%zR81!q- s BHLYLw @  dY??3+103>32&#",̸h~BA8#%3Hw dY ??+10654&#"5>32H569HUa409 ,KG%{^Q  bY@III@ I   cY  ?3?+9/_^]+++_]++9102654&+#!!2!u_xLN;fXχmZK3B`^49%^O@ bY3II@I- I cY?+?39/_^]+++_]++910%2654+!#!!3#Yz;HT`-ZZHy)J^`s0F@( ++ &+(#(cY%# cYcY??+?+?3+9_^]]3310#"'327#"&54732654&'.54632&#"=_6J04H`} _PfJ^y`ɢcv9F@X{nqIu.0ZA8+D4D\_T3+';-?#5#@ ]Y ]Y?+?+102&#"#"'53267>]>22e'WK.80E %#w˹@;F#5#-@cY]Y ]Y?+?+9/3+310#73>32&#"3##"'532671h%]>22ed1'WK.80E 豩w)@;w @dY]Y?+3?+310327#"&547654#"5>32JR71KsP*6LP3 HE\i DA;5##@@'/O_Y  `Y ]Y?+?+?_^]3+_^]3103>32&#"3##"&546326?#"%%]>22e"1vo&: /7P~:f1RD Ue0f^"@ H??3933+10)!!DX69aXD^.@]Y]YcY?+?+9?+910327#"&5467!7!7!!I14H`}%#?s3+PIu3SNN^!C@%/ aY  ]Y !  ]Y?3+39?+99/+_^]10!'7!7!7!3>32#72654&#"=0?#?s3+gyvvGcrH\\,U3^TEmSp6f2-KE-^H-^ *Q@,! !aY  aY  &Y ]Y ?+9?3+99//_^]99+3+_^]1072654&+7!7!&'#"&546"327.n]#s-1V)̥7$Ē;FV6}s[hFblZfڝRo>T53`3BS/1@9+  ]Y??+39_^]_]]310!>54&#"'632/Ӡ_IdLD}IY`}b@  ]Y?2+?93102&#"!.54>lkyhӅ8E`jl5oQڑvy@  ]Y?2+?9310"&'732654&'!`t_ze-ƎZlLEWlKZZs1qs&@U $  $bY$$$$$'#I$""I$ I-$$,I$%I$I$M$$)I$ $$cYcY?+?+9/_^]+_]_]+++q+++_qq_q+_^]910!"&546?.54$32"3254&#";q퍄Zc suQ?odZe/-q pNVPA8=mv?32&#".#"32?#`w4E@*K=07a _<|Pjcjm1L'yXL Vs&qԊcn%^$>@'fY `Y  /O_Y?]3+_^]3??+?+1046;!3##"&4632#"2?#").",ĝv_WILX\IV /:Pci=:0"h^@ ??399?103! !7!!6?#PyI-Ӡ $ f\H\Ao+%7^]Y?+?103!!%-1^Z#-.@]Y ']Y ]Y?+?+99?+?10".54632367!2&#"!>7#72>54&#"XMSy6E.[A50g/4:H=FuMKAD{II_gJZrXuZ^LwP`tXX//D@& bY 9+  ]Y ??+39_^]_]]39/3+3103#!#73>54&#"'632/+;=+:_IdL D}IY`}bD@&bY  9 +    ]Y?2+?9_^]_]]39/3+3102&#"3#!#737.54>lkyh9+<>+8E`jl5ƊQڑvZ(+C@$*]Y))]Y #]Y]Y?+?+99??+9?+910"&546323767!!!!7#72>54&#"Rw5L-^+2G!FvOKAD{Iߏ)eJZnUfJSWNuP`tZZ1>V@.-)(aY((!dY++hY/ 9]Y2]Y?+?+99??+9?3+9/+3?10"&546323767!!#"'32654&+7!#7#72>54&#"Rw5L-^V)ÚդLK|.G!FvOKAD{IeJZnUfJ?ќP +3iuWNuP`tZN#)69Cd@8@@/@ @aY8%%]Y %77]Y' 1]YC**]Y"?+3?+99??+9?3+99/+_^]10"&546323767!!3>32+'7!7#72>54&#"2654&#"Rw5L-^+gyvvGcr=0?G!FvOKAD{Iߏ-\\,U3eJZnUfJSp6f^TEmWNuP`tVt2-KE^L1H@')## #1cY  ,,cY 1cY?+?3+3?3+99_^]]3310#! 547#?3!632&#"2654&'.547#3 sĄ1OEȢbv;D:]}mcT@htesXq2>T_T4*%:0@/0)?;@`47J^%.5@"]Y]Y **cY @ &]Y?+?3+3?+?+10%#"&547#?3!7!2&#"#"'5326727!k sĄ1/I'[A5/e'WK160D y]ns1~2>TgZwϹ@;\#wJ^L4>e@9(0-0cY75!5aYI)  +@*-!]Y!9cY]Y ?3+?+?+?39/_^]_]+99+99+310%27&54$32.#">32# '#"&547#?3!!%"32654&{\6gBMVaH{iyiiU sĄ12s]*Rb4N(2[H"pqA0rhYCZ~2>TJnZA6#.%<C@$144 ]Y4 /cY"/&+]Y(&]Y??3+3?3+?3+3?+910"'5327654#"!!!"'53267#?>32&#"!3632hF=6$m]+bӽMhF=6=\̣)ðhPE@9F Ќ)F1{1yPZőTT1PA>䨚Lh%}&A@#%$  cY"cY?3+?3+399_^]]33??1032654&'.54632&#"#"&'!!PfFayaɢbv;D:]zpޟaJ-5jA8+A7B[_T4*%:0>`+1H%= (@ ]Y ]Y?+9?+9?10!!!! =+1J--^SaV 7@   ?33?399//39933399310 #333  #333<<߼'%P'%P%J@/ cYP@_O  cY?3?+99//_^]q]q+310!#!#!#!#}l!!w'$@  ]Y  dY ?+???+9104&#"5>323267!!>7##"&54?6((+6LP35l\,b-059- 09 @ED3{򴪦[nw2+@(++]Y+"]Y" dY ?+??+?+9104&#"5>323267!327#"&54##"&54?6((+6LP35l\,b- P71KmZBb- 09 @ED3{@(&H{r SW[n@  W  T?3??3910#654#"#33632Zf PDo"J+,ekl4$\_n8P $@ Wi8HX T?3?3]]?3910#654#"#>32&#"3632Zf PDo"JwL("+E)ekl4$\G2n8PX @Yo V?2?]2]107"'5326734632#")O4,*.E:@HAqBEs=B`zABZ733673#47,,% 8:r ~qjF_#nTCs^@ T V?2?3?31033>73#"'5326?+ $C,(0F^#{N&g?C RA%jRj sZ jq8/1032654&'7#"'y*:* `iu'00&2z]mjq8/10#".54632{*;* ]lt00&2x^n!@ H  ?3393+/107654&#"'632-0*0R,51&.>ow"f!@ H ?3393+/107&54632.#"ZrL(K3;JZR-hF@C89@@[/10%5% $A@Hx@[/10-5B$xHVH/10 #3JwGVVVH/103#/wGHV)!v!CVJo)jdM^C"?5T^vq"?5J //10 !wJ-J/10 vJ"PF7eFuV<"?33103!737+T+b{{Vf"?23107#7!#++V{{-P A@+   )`/]q3/]33]]]q22/]1073733##7u{{P7@ `/]q3107!u{{L'3  /3210%327#"&'-,.;>Nx~a^Nh^P-Tq~3 ?/1077''7 i`Fak^CX{{Xy{VyyV{@  V?3?3991074?33673#"&72654'm;A7?#|xUe',2zTP`L^ZJj~d%M@=>;w%1\ T??10#3f}y#"#@   W U?33?33993310#"&'532654&'.54632&#"ٷQv5wy=L6I\FvJe[&9*G[SC1)"0)4cFE?"#*&/m) @  TV?3?3991037!# !V ^5\^@  T?22?93102'&#"#.546wMVg(UMObplyedc&60dPO)>l@ /3/99310!#!5!o @  //9/3993310!#!5!3oR$@ //9/]3993310!#!5!3o^ @  //9/3993310!#!5!3oV@ //399310)5!3@ //3993103!!$@ //9/]39933103!!#odh8L 0>+]5-dwj R?39/310#3RdŚv%9P?29/3103# bŚu=/ @?2/]393310%7% //!1dۓ}/ @/]2?39331077-)!f/dܔ}bC Cfj?Sf?GSf@dXR) "?5s!Z ?55s@ `/22/]10!##Tmsms@ `/33/]10#5#5msm#w; /22/1033#mTm#w; /33/10!5353wmmVN@ @0"?]210!3!53NnsuVRVN0"?]10!3!NnsVRB 4@ 0@0@0 ?22/]3]22/]q310 5!!Rdy{m!K6EM{/210!!<+I+N\OKjRcPm!Sn!L-F) ?10#FLL)d7)?3210 #!#!LI%KK)dd` O@*   @ H @/' H /23+]q9/]/+]9/10# 33267%4632#"&`"͘ǓYqLA2CID6?+R]MGJ13BR45+1@  Z j 9 I  /]qr22]]]]10!2#4&#"7RIQNcR~&A<6G*t"  "t"_[C"?52__vO"?5BB<@" ) `pH/+]2/]]2]q3/10373#7#Tᾅ{B%>@# ) `pH/+]3/]]3]q3/10##33 TDžqbj 0/10!#!uX>jg; ?10!7>/ |D'`a_ sj@ ?39/]310#".54632{*;* `iu..%/v[khV/"?33103!7379+T+b{{VZ"?23107#7!#-+V{{-F A@+   )`/]q3/]33]]]q22/]1073733##7{{tM H>++5j   ?2/]10"'532673TWA+819 78':<')j ?2/]10"&5463327/x;3P,4G)n* Fr~jtz~>+55mb <@Xh) @H Wg&?3qqq9/+3qqq10#"&546324&#"326bonpo5,+5`,5g~hg~e*00*Z0j;9}RzLpQK H>++5B@ 0 `p/]310!#7!#J171b%@  0    /]3223/910#"&'#"5473326733267Ir:KNEao[3L`\3M}Ek=$#G( TBEVBEiLz H>++5gKi H >++5GNin@ H>++5Gn@ H>++5YRv@ H>++5eM He>++5DH/310!7!'j:_R$N:/210!!;+K+hP/10 djoB /?10 #BAu@ ?39/]31032654&'7#"'*;* bfv..%/uZlB@ @0 `p/]210!3!73)J//B\`-P/39/310!!37#hX)-!@0 /]3229210>32632#654&#"#654&#"ln%BpTa n"83Lc#83NnHHTT% !5BE"5BE3 ?/1077''7i`Fak`DX{{Xy{VyyV{0@0/104>3"#72654.TPR;N++55RP?]210!#7#{P3{3)-3@wx  /]99//3]]3]]10"''7&#"#3273267337LJ\J",/s9:AA\C% (3u"w/}8x:9%s7q/CL{F".=@%   /&&/3/]99//3]3]2/310".#"#>32326734632#"&4632#"&N*MFA+2r~Y.RG<+4uE~LA2CID6?oMA1CID6?#+#:9#+#5>wGJ13BR4GK23BQ3;N/@Xx$)))w))))$$- wx  @H -- /q2/+99//3]]3]]99//3]]3]]10".#"#>3232673".#"#>3232673V+E<6'.s~Z+G=5)0u +F<6#-s~Z+G=5(1t !(0p{!(0p{! 8q{!)0p|?  /329910%377#'3?9/33107#7#5yy3% !'/7AIS]gqy@w  &$622?2O2_2?O[ooVjv~~rzB88F< QeeL` .*0*@**$2jz<`**`3 #4#"4632#"&"͘9YpJLA2CID6?]MBHJ13CQ37H    /]/1077''7VhdaegVid`dVfd`diVgead)  ?2210.'5673x/x/qKI3gh E7/gR  ?3210#567&'5dt)iSRjiiH34f!) @  ?33/329/310>73#&'##567&'5s"UXh.9-ig2X)iS3BDM-@+5@ ?39/9310"#>3232673#".+Gs/ٔ]ZHp,ݖwL;6 86#)#H %@IY8@P /3]2]]]10 #&!"#/k3omHefj+/9910!5 5! Ծы )@ X Z [Y?2?399??310"&54>32373#7#'2654&#"/\iWXz2#T+Ci.(Ae)xxhZC\h-9{n))"@  [ 0 Y?3?9/310"32654"&54>32+3267:a bjbsn~־A<.\E@rweG>2Om\@GB) [Y?22?3310"&54>32&#"3267F~[mje;M?Qij0Q,`)}z-$|x1)"@X [Y?2?]399?10"&54>3234>73#7#72>54&#"7\iVY1J$ )̒ &^ +H2-)Bc)ywނ,<`;/\08NH3;zn5@   [ X?3?3]910#654#"#33632/V F:]=Ͻ##Tp[Y5,M~ѪEjn]885F& @!Z## X[?223?3393?1023632#654#"#654#"#33>YWY WV =:^>V =9_= 5io\Jb,M%%MNAF5{ Z X[?2?9?102&#"#336=!))GnD [ no)FN5 Z X?3?310673#3/XS:uA5 @  XZ?3?39910 373#'#GٚNVp]8?5\=  /]9/10!5>73RC.A;J@sCZs$@V#i#X#M#)#9## # #,'I#&I4!IIIkI  ]Y ]Y?+3?3+9/_^]+]]+++++q3^]]]]]]q10"&54$32.#"32674632#"ו\6hBUM[QLE_WILX\[H"߀`a/#O)WY>:Pcs%@V$i$X$M$)$9$$ $ $,'I#&I4!IIIkI  ]Y ]Y?+3?3+9/_^]+]]+++++q3^]]]]]]q102#"'732>54&#"5>4632#"ٖ򬷐\5hBUL[Q=z\H_WILX\sG#~`a#/%+WY>:Pc1sb(4s@ "cY p@2 I /6 /aY// ))/) )aY ]Y ?+?+_^]9/+_^]99/_^]+]+910>32#"&54$32#"2654&#""32654&%W$IZǔ~ιOq^H c9~*^1IS:HN\б5m߳QeG8syE79,"'m'Q%T ?55HV&Qj#R %&+55Z+^,.@#cY+ cY 'bY'?2+?+99??+10#654&#"'632!327#"'5326?&547)3+'++Hj$J y6&P'VA)929 !OϹDACZLAy:<=Ӕ0@iY' I/ I7 IiY??+9/+++3+10!&54$32%"32654&79ĹX꓏ӹ6Cr}ZTs@ ]Y ]Y?3+??+10!.54$324#"32>TfktяKwKKxC&/˖Mz}{4@ nY I*   iY ??+39/_^]_]++10"!3!.546$32&}[o:F^o54&#"'632!327#"&5467L#%(.-^q#"L >.6h-*w"H%yk1fB(A1 sd:k>3#%4@ "! !cYcY?+?+99999910327#"&5477654#"'632%?-,13NlH9)V39..-SsLZ"#*}kY%PY22#xiZH}b0OXj@? jYjY  @  W g 8     iY??3+9_^]_]]]]]3^]]+333+310!67'%754''%&#"'63 z5E7@sj7_25PkX@TZX@3 `Y`YP` @ [ k      gY??+9_^]]]3_]+333+31067'%&''%&% {q_sa{Qqe'3TF/*@+,iY+# $  iY ?3+3?3399?+10%##"'##"&547!3267!3267!#!!27 HhM Sq3u%1 s02'X76[abn>;BE.\B5<7^l^.*@()cY("]Y?3+3?3399?+10%#"&'##"&547!3267!3267!)7! 767+m Յ-b\/`-c]+c-9A1=#vm㦛Ik}sD3{sF1{>qu4@iY iY@ I  ??9/++9?+310&#"3 !!67##"&54632R@7IvEiB/e! αʐsh`Y/J'hǹ+1Zs#@]Y ]Y ???+9?+10&#"32!!67##"&54632HmKa_-T:L_?Hq kE]Oۺr5"@iY iY #?3+??9/+10632#"'32654&#"!oo\sƭzmeP=8%i13V% ^"@]Y dY ?3+??9/+10632#"'32>54&#"!?Z?M›Rfw_LWU,*^^V+6sρ;^%`,>@%O_ **(#iY#iY?+?99+999_^]104&#"&54>323267!"&5467>-M:Uayᖹae9^XX;?E'7\ɧI-DYs+:@! H))) )!cY!cY?+?39+9_^]9+104&#"&54632327#"&547>QATj\ŀj8iUEzZ5IZ~c6(;GLѨ{ĕO7OeDY[ZVٳ [4D]6@iY oY?3+3?9993+9910.#"'632>32&#"!7 !=),6/`^Xt(FS\PN$.'LC'H#\?1WM)P`ZV)=[^,@cY cY?3+3?99+9910.#"'632>32&#"!7 !9"+1'B`Pj%FzSY:C&,KC"%j;4@?H7!X{&*@!iY iY iY ?+?+39/9+10 3632# 54$3 .2654&#"{ۈv|, hWҍ͊lˇk'-%kqkZs&7!Y!@ I!! ]Y ]Y?+?3+9/++910"$54$32&#"32654&#"7>32?$Z\jYjgZsHE)YI194J+^#%@cY" cY ??+99??+10#654&#"'632!327#"&547)3+'++Hj&J y-+?[OϹDAC}_LAys!/V@   @( H   H   )]Y"]Y?+?+9?99_^]+_]+33]102#"'#!654&'.546"32>54&vX_'8fp{7{9RORs©X!'=Dg_A28+:vwifZsFM{{Zss5h{7&5@  ?3?39/33310#!!3!!6#15ic HFJxY1^ $@  ???9/399310)#!!!F۸զXV^'JLdhs%H@,]Y bY@ 'H@H ]Y_?]+?9/++3+3?+910#"'!!!7#73>32"32>54&h_N)s)s.֝NWj"71dFsMB|uuoXpXb{7%o@J#}Y 4#I*I4I"I5I, * I" I iY iY ?+3?+39/++_^]_]+++]+q+qr+10"327#"$32.4632#"&Ӏ\}ovjkaDRnYIRˢĴMM+-<;&ZlLEWlK%o@J#}Y 4#I*I4I"I5I, * I" I iY iY ?+3?+39/++_^]_]+++]+q+qr+10%2654&#"63 #"&'74632#"&~jwF/kaDRnYIR;NND/9(8ZlLEWlKTR5@"V7GZ9I(o /]2]]]]9/3]]10#".#"#>323)3HyhY&+4>vvw@"("4;&-&{4ZsT:}^Z^^#@ aY ?3?39/+_^]10!#!#=m?l ^G121^O@2aY aY I I %I "I I    aYaY?+??+399//+++++++10)!#!!!!!#7=)3f+>a<^13s+9Bs@F>!bY0>>>>> >>:cY 3]Y ,]Y *&& &hY?+_^]3??+?+9??+9/_^]_]_]r+102733>32#"&'##7#"&54$!374&#"56"32>54&267#"Dm/ IZ]2 9-YM63phBJaH}JBFDxFAX-s7<^ZL׿KXZ3;'ae/'V~P`}T\FuaS^^$N@/aY #II"H I$aYaY?+?+9/++_^]++33+331023##!#7332654&+732654+bO'+vg'\%VdAD%qW_q^}{wK6GcZO}w!-^ v@OaY''I"&I/!2I,III7I1I%I"I I aY aY?+?+9/+++++++++_^]_]]++3+310)#73!2254&+3#_k+ib'pcV9)5;>}w9^ ?@( aYII%I"I IaY aY?+?+9/++++++10)!!!!!d)3f);^do%P@0#aYaYkII"H   # aY ?3+?39/_^]+++q+9+910#"'532654&+73 54&#"'>32dj}r{r~h%`FHRprj }d=J\ZIB6A\G4J?^@  fYp??]+10!!#"&54632-`VIM]W^WY>;T^^  aY/+?10"'532673VAJ=>J\(Yc!9R^ @  ?3?39910!##37!j^Vrt8A3b^u^ T@1          aY?+?99_^]]]]3399]]]]33103'737!9N+NqTkP?'hXq99f^@   ?3?3?33310 !#67####!?qCP))o--JLf^9^@  ?3?39910)##!37>3q  zT^=@<V+o @ aY aY?+?+10#"&54$32%"32>54&+ל\ZWd[ZUaVsskzqo @aY aY ?+3?+310%2>54&#"5632#"&'7%f]fqhՙfIX6o~9<%(+\%^ 3@ gY gY?9/+9/+993310254.#""$54632)w퀸 PTHxMsэ 9\H^%@   gY?9/+99//3104632'>54.#"#&\ZG#߀``/#Pg?ٖ򬷐\6gBVMZRKE^$%'@"! gY!gY& '%?9/9/++9910%"$547'7632'4.'6%3'5mkM7Xohj5mޒPwvC@% wjmwH^FTAOzH$LzJf 13s!.7j@?3bY033333 33/cY "]Y )]Y cY?+_^]3?+?+99?+9/_^]_]_]r+102632#"'#"&54$!374&#"5>2>54&#"267#"`t0޻܊gM63g`WegFqEIHmJxX-sKG)[i&01%ny[a`euaS^B^)*@ aY$aY?+?39/+9310!"&5%&54?332?3"32654&KGl #X^0iersk-yRẦk@.*?M}j}oM[v|IYbTs@  ]Y?+?9/310!654#"!32T _#5KFFKſEL^&@aY  aY ?+?39/+910#";3!"&54673B>FN7h[~s?@y(Rj^@ aY?+3?10!#!7!!,)w^@  ]Y?+?310"&547!3267!+- _q-=ǷJL^>-j7\-@gY  gY ?3+339/3+31073254&'%'#"'7D2{1_wlIk-l[,b-NdDN\"-B@ #))) gY / gY ?3+339/3+399//3310%3254&'%'#"'.54632"&54632F1{1^ykDMP84HXoMP84HX-l[,b-PcMHNV'^/1V%^@  ?3?3399310#33?33>3!476#E5gx^-C{)o]-4U}^ $@aYaY?+9?+910)7!7!!Li)f^0@aY_Y aY?3+?9/+3+910#"'532654&+7!7!們v0=ubbs!+=/__LH5o),@ !aY aY ?3+?3+9933104&#"'>323267#"&54>7>V>95iIBiQBmO'GB={mE{6\E'P-/ -Zc7,2;'6;-E^d.$+8o""@ aY?3+3?93310327#"&'#"&'73267&54>32R.M%C@:`mD{\-U'24*ceqzLYE"]x}X?gtp}/}^aY?+?10!#!!`'^^ ?2?310#!#&5}3g+:^`9Z/T^@ aY?+?310!#!#!h7b^9^)^#@aY ??339/33+310###"&5473;332673DH MR SU Ձ pqTZRFF7!#/=xqt93&&?UTm@|[czL #@?  8  IN?3?3]9/]3]10'!#!.'=}9c}}7R@1 F  ?   #I IH   INN?3??99//]++]_q_]3_q3]3310!7!#!!!!!%3#3Ŗ#'/X%7qXF߰?<@&II &I"I IMNI?2?39/_]+++q++3910! #!32654+ 32654&#CbwhRVsb}X\fT7`iNX`oNg:CdsPD4A#D@* II &I"I IM#IN?3?39/_]+++q++33333103! 3##!#!32654&#'32654+LJVCcL%|&s^f7`iTRT}X\g\E5FPD8=:CdIN?3?310)!22654&+;{ofqj 3@G  #I IHI N?3?39/]++]_q3q10!!!!!!O&/X%7p߰ 3@G #I IH NI?3?39/]++]_q3q10!!7!7!7!!r8$Y/'Rf߰w;@$IIl{ JtO?3_]]?33]]9/_]++310!#"&54$32&#"32?#oʘPsjn^_n9>-7л+C=xyqw /@+I%I_L IN?3?39/_]]++3]10#!#3!3^y^TTJsd @ I N?33?3310!?'7!;)po{97{{7n9 @ v NI??2_]]10"'53273?C>E.###+ @  IN?3?39910##37!YKkmd1Zb IN?2?103!߲'@   IN N??3?399310 !#6?####!}5g!u+.d)-lFZ)#@ IN?3?39910###33>3Fi' rJ/@ NN II??3??3103 3!#67#!hFai2n !@ {  JtO?3_]]?3]]10#"&54632%"32>54&ˆsSP\TTMW?ε.ށfi{܈^q'=@$ { I#t##O?3_]]?39/_]3_]]9310!"&5467&54673326?3"3254&˅ԅyghk*8{hIƿx%>w$PNh\mqѣkdOS '@w  xIN??3]9/]3]10+#3232654&+8p`9L:Eqj-fHB%#PJ'X@K  @ I k  ֲ I ٲ I @ I O$L?3?39/+++_]]+933]9?103>323267#"&5467>54&#" /uVZj i6n;1pPj[1%Bah5Ar^3L!Eri HB#%OK@N K LO?2?3]99??10"&54>32373#7#'2>54&#"cv]e8' _-/[54/Imsdes`c2?~y5+6?r@L)';!!!!!!!I!I-!!, I !!!7ON 1O,,,K''' *L?222]?3_]]?39_]??39/]+]++]q39102733>32#"&'##7#"&546;754&#"56"32654&267#"-Kd 8ce@&(ta DG=<ч{ՃB9jUB;B @ LFNO?2]???39910"'##33>32"32654N7'+9V5et`)3S63-Imqc5t[H/yYS8CՃy!#@NF LO?2?3]99??10"&54>3234>3#7#72>54&#"etab9R% : *j 1R74.Gp22? 2He3@XP8CԆ<=!D@$I I~ H{L  O?3]3?3_]+]9/]++3]10"32654"&54>32+3267=lkxm{#JB2\Uz5nPC:Aqod?J&;!M@2,I$II/ I+ I' I O L?33]?39/+++_]++_]+3910267#"2#"&546;754&#"56;jg}mŀy#GB9\Q~=kTC<@od?J%<q'i@F && In&&I&I&3 I&. I&) I&& o   L  O?3_]3?33]]9/+++++_q+_q3_]9910#"3267#"&54675.54632.#";gQa>;Rt0pot8;p@3b>3232>54&#"X$Lv=5 @W  `pNK??]2]103##"54632bӦѱC32d7T0iQe޺c~]S󢉔@  OL?2_]2?33]102#"'732654&#"56gx{f?%F/Yv>95Z0j͔1BC75  L?3210#654#"#>32dB`֩41=(hܤ5@?   O?3]q2102673#"&5473%?\Ӧ R{hԢ02/3y^ @ KM OL?2?399??102#"&'##336"32654gt`d;R# 3 b'3S63-Im˖4?tY^tYU8AՃ{b!@ KO?3?3]3]31027#"&547#?33#0@JnibPh]##NP%X\;wf93@ O N K?2??3910332673#7##"&547La LBhCѤhdc<2"TAxgDP%@ N K?3333?9/3331053254&'%5'#"'.$V uj9D/` KBgFХf_i%"@"N$ KN?333?3393?10"'##"&54733267332673#7#Tfab\_ F@iD^ DBiCѤfxg4I<2"TC<.&TA K N?3?3107673#3\^(Uk3!@ LO?333?93310327#"&'#"'73267.54632?2.0+NDe0LuKH'!-/(:%0(nb'"32654+732654&אtUfYh3[3#\a:{^B3|B''@ "O  G?33]?3939310&54632&#"#"&5462654'!kYgi5Z;B^ @ OLLM??3?3?33310.5467>32>54#"GwQ[hL|Dgk|A@^PlwQch Č{{h @ MKL?2??3399331023327#"&/#'.#"'6UXt2%*=JXX$%@an?/" clpg5, ` @ oRP??]210#3'4632#"ӦѰC32"32>54ȢsB0ϛ ^l-j7L[i&0.(saS_h)6@\TdtE&6 [k{J)9 / /##*]Y#1]Y?+???+9999//_^]^]3^]]]]3/3/3]]]]10"'##&#"#>327!3273#"'3>32"32>54bR:H v-#D& r$K|NDHvLJACzKjE mNV?˶~|qP`uZ,9@Z(TdtE&6$ [k{J)9 $$/$ /$$* 4]Y-]Y?+?+99?99//_^]^]3^]]]]3/33]]]]?10"&54632376?&#"#>327!3273#"'#7#72>54&#"Sx3H "s-#E& rG!FvOKAF{GVKYLVjE mXWNzrM\z%4@S'$'cYt***e*6*F*V*'**00 0@,,[ k { J  ) 9    $ ]Y]Y?+?3+?39/3_^]_]]]3/^]2/2]]]]+310"'53267&#"#>327#?>32&#"3#3273#"'-hF=6=\tH v-)ðhPE@9F 1?E& rmMPZ)jёTT1PA>lws,6>l@"'"bY/-87'  bY%@&H%%%'''!(++!4<<?223?3393?9/3/]9/]++9+91023>32>73!&'!.'!#73367654#" 654#"L+Fh3H N>DKX LSU(dhaDZ gbQ)b@ssptLhGU?% )j9 #D3{74i1{rJs *d@9)]Y bY !$bY ?3?99//]3/]+992/_^]+99?+910>73!/!#733632>54#"B(1+tHNbh&0CZ Ί NQl :8s--35>1䧛#U203{hs*7w@L& TdtE&6[k{J)9 #### (2]Y+]Y?+?+99?99//3/3_^]_]]]3]]]]3/?102#"&'#3273#"'!7&#"#>32336"32>54-Sx3E&s)H v :JyMJACzKsJYGv mgjwP`uRs$m@G t e 6 F V '   @[k{J)9  #eY?+?9/93/3_^]_]]]^]2]]]]2/?102&#"3273#"'!&#"#>32336J;%B-7r&D& rDXH#uj s mmFLw#l@Fte6FV'  @[k{J)9  !dY ??3+9/3/3_^]_]]]^]2]]]]2/1032673#"'!&#"#>327>32&#"$3 rCXH#u,̸h~BA8# 49mu%s.R@- # #  cY(.[ T.. .. cY?3+?399//_^]]]]33+993310#"&'532654.#"#67&54632&#"2673=kEPf>1W*4ɢcv9F@X[4);4q#ZA8*=Vl:0_T3+';-/339BuoL,x@McYt"""e"6"F"V"'""' '$$[ k { J  ) 9    @]Y?+3?39/3_^]_]]]3/^]2/2]]]]+310%27#"&54?&#"#>327#?3!!3273#"'Aao !H#u'Ą12> D&F#5~2>mTmTJ^ @]Yp@XH  @H  te6FV'o @[k{J)9  ]Y?+9?9/3_^]_]]]^]2]]]]99//+]+]+910)7'#"#!27!7!32673#"'!# 7ABG=s3+=:,C>^-A3#3>?s-:@! ]Y']Y 0 ]Y?3+?_^]+9/99+10#6$32&#"3>32#"&'#"32>54&2f`iLQ]<eHvIK?F{IK)y+V`gsO`JٽI[uP`xXX; M@1.I.II I< KN?3?39/_]_]++_]++_q_q3]10#!#3!3BB<6;3w^"8@ ]Y  bY cY?+?9/+93+9910%!"&54>7'7%!7!%"32>54&c 3-'d|k+yT^MwBUTں peRe#O_X]S[f8Z@0!%6,%1]Y% 7 78cY@8]Y?3+?3+399?399?+??910%27#"'#7&547#?3!!!733>32!654#"!AaoO4! sĄ12mh-Z;>dӉl\,bӣ#5T\\}M]NfD3{1 {^ ,@bY*I#I I ??9/+++3+3103#!#73!ߜ+dd+^-)^3@ bY *I #I  I ]Y?+?9/+++3+310%27#"&5467#73!3#B_o+`-^+#5}=@ǝHs$,f@>  aY(II I*I#I    ]Y %]Y?+?+99??9/_^]+++++33+_^]331023##"&'#!#73336267!"!754-g+\9Sx3 H͙+^ KAy%JHs&bs=JYls-P`ul%^C@(bY *I#I I ]Y?+?39/+_^]++33+3310"&547#73!!!3#'267!++^-^^-^+@[n wǷ@-@@u, H^'c@<cY$    bY I I I *I #I    ]Y?+?39/_^]+++++33+_^]33+33310##"$57#7367#7!!&'7!#3267!Z b+tN1!2C{)O11V)#hvׇ2ǓHyW]ev;toy%)h -1@  !]Y (]Y cY/+?+???+910"'532?"'##!3>32"32>54;[<+7_4R:J->)+NL\PA' JxNJACzK)wsubHؾi͵VuP`uZ)#07@ +]Y$]Y cY cY/+?+?+?+99?10"'532?#7##"&546323767!32>54&#"\<-5_TG]Rw5L-mL'FvOKAD{I)wWNeJZnUfuP`t%-I@'"'cY$""/+bY.@ cY ]Y]Y?2+?3+?3+3+9/3+10"'53267#?>32&#"3#!#"'532?!-hF=6=\̣)ðhPE@9F 1܇R'\<-6^%#MPZőTT1PA>ws-;L@) cY =bY=@,)")5]Y)".]Y"]Y??3+?+?+99+9/3+103!#"'532?!#"&'32>7##"&5463232>54&#"R'\<-6]$4h[h8HSZ@DtNJ?G}GL^wF)V_a^LֿbE_}P`yXX%))@    cY cY/+?+???910"'532?#!!3!3\<-6^9xJJ- % XL')wHJ9v,y)@ cY cY/+?+?10%3#"'5326?#!mL'[<+728 J-;<%)s38@/11$. cYcY))]Y?2+3/+?+?393?1023>323#"'532?#654#"!654#"!336L+FhVmL'\<-5_b^(`Ӊb\+b sptLhbwD3{/D3{1^%)ms$-@]YcY cY/+?+???+910%3#"'5326?#654#"!33632mL'[<+728 l\+b Ί;<D3{1^䧛Ikhs -6@ cY .(]Y!]Y?+?+9??9/+102#"'532?"&'#!336"32>54-\PA'[<+7_4Sx3 HV :JyMJACzKsk͵wsJYJwP`u)s+@ cYcYeY?+/+?+9?102&#"3#"'5326?#336J;%B-7t%;mL'[<+728  s ;<^)s/;@, ))$$!!cY cY cY/+?3+?3+9933910"'532?#"&'532654&'.54632&#"^[<+7](*kEPfJ^y`ɢcv9F@X{np/()ws#ZA8+D4D\_T3+';-?`h߶##%3@ cY &bY&@]Y]Y?+?++9/+102&#"!#"'532?!#"'53267>]>22eR'\<-6^%#'WK.80E %#wDw@;Ff)^!@cY cY /+?+?391067!3#"'532?!!@)CL'\<-6^'--.Rw^b)^(@    cY cY/+?+??3910"'532?#!!!3\[<+7]9}Asb-K()wV=!N)^-@ ]Y   ]Y cY/+?+9?+910"'532?!7!7!![<+7_#?s3+N')wSZ)s#17@  +]Y $]Y cYcY/+?+?+?+99?10"&5467#7##"&5463237333272>54&#"x$Ra'9oLP,4GENM?D{IC)n,gTP FG]tXXZ)sZ#+93@!]Y!]Y) 3]Y,]Y?+?+99?+?+10".54632367!2&#"327#"&54767#72>54&#"XMSy6E.[>20g R81Kp ")H=FuMKAD{II_gJZrXw0 H|44^LwP`tXXZ)Bs'0c@< cY    //+(+bY?+++++(( (cY hY?+_^]?+_^]9/_]r+93_^]/+10"&54$32!#3267327#"&5467"326543g`We[P.2Gex "X-U[i&0X Fn+saS_')/s5k@!4  4bY4I4 I4I4@!I 4 44( +.(.cY*(]YcY/+?+?3+999/_^]+++++_^]910#"3267327#"&54?#"&5%5.54632.#";xZV\^\P-4Gey $,HPV\\HahadMD8=)1LFm,.}5qGV.$@=40)s2j@$cY$12 1 21bY2I2 I2I2@I 2 22 * ,,]Y cY ?3+?+999/_^]+++++_^]9/+102654&#"'632!"'327#"&5473 54+7όtDVEMH|dTP.2Gex _-;D.4-"Vg%8 Fn.,Xu3)s*3c@267#"`P-4Gey pIűM63g`Weg;X-s&"% Fm,.ף)[i&01%RuaS^%)#@fY cYcY/+?+??+10"&5467#!33274632#"x$-mLP,4G_WILX\)n,^ F;WY>:Pc)s)$@ ]Y]Y%cY/+?+3?+10"&54732>54&#"5>32#"'327x ^3@UL[Q=z\Hiٖ,.P.2G)n,.$(~`a#/%+uF+)5## @]Y]YcY/+?+?+10"&5473267>32&#"3273x R160D %]>22e&P.2G)n.,@;mw s Fo)^'+@  ]Y cY#cY/+?+?+?3910"&5467#7##"&547!3267!3327x$T ͊-l\+b-lLP.2G)n,㥜]x\sD3{ F)R^%@@!bY]Y]Y!cY/+?+9?+9/9+910"&5473 54&+7%!7!!"'327x _1t%\'3y+#FlP.2G)n.,V814 { F@ K N OL?2?399??102#"'##336"32654etc`:) ^+5U43-Imŗqct_S1?Ӂ{X LO?22?3310"&54>32.#"3267ey}d?&F.Yv?85Y0h4ˆBC 7jH(!@ L# O?3?339/9310"632#"''67&54>32."32654&oSxdoUgMT? AXCex~d@%FIXT[8E%vN`NLm;7e42_>T4N>.$!);@# $9I +OG?33?39/]99]]]93310&'77#"&54>323.''2654&#"VFR]E39+ė[fx?,=NDd25Kc8D'+5ZiIKiϙshVFr\gPq2Ct7?DXF(@  KXhxG\?2?3]?33]310"'53267#?>32&#"3#wQ(3+A sz^H:3)(0#5X9>f9<|#:-+AbX@   KM?2?9/33310"'5327#7333#dK--"\PlkACjhVbww5ˉhz^d@ O M K?2??3910332673#767##"&547J_ L>fD2-_vda@/#T=Guwf;Wj O@4Xo +I'I#II I/& I KN??9/+]+++++333]2]103###733'4632#"jkDEjk?ϮB;f;?iD5;>T6BX KO?3?1027#"&54631>Jlha nmN%W[K91j @  NK?32?3310'7!!?`h^fG54&'qԒCJ?<AJX+&"W8\e''00V '<9^^!f]!%F# KN?3?310#3#&=-&^r'f\)y5 @ KN?39?3910!7!7!!#z-}㢋)yb5"@KNrM?3_]?39?3910327#"&5467!7!7!!3 &*IVb #z-5-3 WQ6e}㢋)y9E@+  KvWg N?333]]]9?399/]3]10'67#7!7!3>32#7254#"L^#zFUPR0DO1%4G{1* }㢋)pK&WFuoB"d;hR!@ MK?39?339/3910!7!#"'532654&+75#FuĒn36p]U\ k6%r_GQ I@06I-I#I\6 I1 I- IGO?2?39/+++_]_]+_]++q310"&54632'267#"3654Ĕvȃ>[&>]%_pT!xLy^@ o /329/]10#&'7374632#"4632#"a;IErDGuJDrDGuw{HKdDO@HLeDO@ o /329/]10>73#%4632#"4632#"I]ID:9DGu`JDrDGu3*KHK5/DO@HLeDO +,V@ $)y)++ Hq@ H,@ H/+33?9/+]+39q333310"54>54.54>54#"'632!!)!!)!#+#1-.D5i ' $$ZiN?  7=   )5@"Y8Ho U 6 F '  /3]]]]]2/3]]10"#"&5332>;Exqp?w(-%Tph)5&-&87")"u@oVG/3]]]210!7!#Vd@ oVG/3]]]210!%7!V#ŝu@YHo/3]2]]10!'!L"Vd@YHo/3]2]]10!'%!V#L9jC@*GWHXIY8oFV7/2]]]2]]99//3]3]10%7%'V1V}}jC@*HXGWIY8oFV7/3]]]2]]99//3]3]10'%7V1V1}}'@   ?9/29102&#"#36%"3MZ=B ^XablHR  /2210&'56731_x-uHmgiG:,g@   ?33/329/310#.'537673%#567&'5"UXi(>, id/_)iSBDM-7++5%h&EM""Ht"">++5{7s&&'z3vR3&+5Z+!&F'zv3&+55+f&'OR&+5Z&GO-&+55R+&'dZR&Gd5+&'M.Ht>++5Z&GM%%Ht%%>++55;+&'9Z;&G9h5g+&'K>+54g&GK///>+55^&( I)R &+55ZB &H I .&+555^&( JFR &+55Zw &H J /&+55g&(K>+5*gBs&HK--- >+5Y&(R >+5YBs&HR--- >+55}&('zNR &+5Zc+&H'zN6&+55f&)O1R&+5%&IO{(&+5{m&*MR!&+5&JM0&+55f&+OR&+5%mf&KO}R#&+55R&+d+%Rm&Kd5V&+jR &+55%X&Kj\T ,&+55&+zm&Kz5G&+N*n>+5%Gm&KNn(((>+5FY&,R >+5Y&LR""">+5^&,dR@ ((&+]555%\ &  &+5555s&.vR&+5%&Nv{&+55R&.d%R&Nd5&.MQ Ht >++5%&NM*Ht>++55R&/dR&Od5R&/'MYmd&+5RnP&O'MUd&+55&/MHt>++5G&OMHt>++5g&/K>+5g&OK>+55f&0OfR&+5%&POj0&+55R&0d%Rs&Pd5f&1OR&+5%m&QO/ &+55R&1dX%Rms&Qd5&1MHt>++5%ms&QMHt>++55g&1K>+5gms&QK""">+5{^&2 HR@-- -0--&+]55Z &R H +&+55{7&2 FRBB@ HBB&+]+555Zi&R F @&+555{^&2 IR( H(&++55ZT &R I &&+55{^&2 JR) H)&++55Zi &R J '&+555s&3vR&+5!&Svs*&+55f&3ONR&+5h&SO)+&+55f&5O`R &+5%&UO&+55R&5dRs&Ud5R&5'MFRd&+5R&U&Md&+55&5MWHt>++5Is&UMHt >++5)Vf&6OR-&+5&VO,&+5)RV&6dRs&VdD)s&6 ChR 7&+55I!&V C 6&+55)m7&6 DR99&+]55&V D} 8&+55)RVf&6'dOR8&+5R&V'dDO7&+5f&7OR&+5^o &WOR """>+5R&7dj^RoL&Wd90&7MHt>++5oL&WMvHt>++5g&7K>+5goL&WKO###>+5r&8j++55or^&Xjz H>++55Y&8RI >+5@Y^&XR*** >+5g&8KM>+5:g^&XK!!! >+5^&8 HR& H&&++55o &X H! (&+557&8 ER H&++555o&X E &+555q`&9RDR&+5f&YR&+5Rq&9dfR^&Ydof&:OR(&+5}&ZO&&+5R&:d}R^&Zdwyf&;O\R&+5&[O&+5yV&;jRR &+55&[j &+55?f&<O#R&+5s&\O &+5s&=K!R&+5!&]K&+5R&=dR^&]d9&=M Ht >++5^&]Mr Ht >++5%m&KM Ht>++5^&WjW@ !!!>+55}&ZP  &+55s&\P &+55Z&D/&+5 &AO{&+5)y#6@oYiYlY??9/+9+93?3+103!2!"'32654&+5&#")>/ %댑ӅBQ{+8|(&*K--ykThZX&~6&+5ZX&~5&+5Z5&~ 6&+55Z5&~ 4&+55Z5&~+ 6&+55Z5&~+ 4&+55Z&~ M&+55Z&~ L&+55&$Gt?5&$+55V\|'$@ A>+55'/X&/-&+5'/X& ,&+5'/5& -&+55'/5& +&+55'`5& -&+55'M5& +&+55fV'(Gt ?5V'(+55]{|'+@  A >+55`X&;&+5`X&&+5`5& &+55`5& &+55`I5& &+55`I5& &+55`& .&+55`& -&+55p',Qt ?5',+55||',V@  A >+55ZTX&R\ &+5ZTX&R%&+5ZT5&R  &+55ZT5&R &+55Z{5&R#  &+55Zf5&R &+55pH'2Qt?5H'2+55Z5X&D,&+5Z5X&+&+5Z55& ,&+55Z55& *&+55Z55& ,&+55Z55& *&+55Z5& C&+55Z5& B&+55pr'vQt"?5r'v+55||'vb A"">+55Z!&~1&+5Z!&~+8&+5'/!&Ē(&+5'/!&/&+5%m!&&+5%m!&+&+5`!&&+5`!&&+5ZT!&R&+5ZT!&R "&+5w!&&+5w!&#&+5Z5!&'&+5Z5!&.&+5ZX&~'X6&+5ZX&~'X5&+5Z5&~&X 6&+55Z5&~&X 4&+55Z5&~&+X 6&+55Z5&~&+X 4&+55Z&~&X M&+55Z&~&X L&+55j&$'Gt?5j&$'+55V;|'$'@ A>+55mX&'{&+5mX&'1&+5m5&& &+55m5&& &+555&&9 &+55}5&&% &+55&& 4&+55&& 3&+55f'+'Gt+ ?5'+'+55] |'+'H@  A >+55Z5X&'D=,&+5Z5X&'=+&+5Z55&'= ,&+55Z55&'= *&+55Z55&'= ,&+55Z55&'= *&+55Z5&'= C&+55Z5&'= B&+55p 'v'Qts"?5 'v'+55| |'vb' A"">+55Z+&~N2&+5Z&~M#3&+5Z!&~&XA&+5Zs&~XZ!&~&+X7&+5Z&~R9&+5Z&~&RX9&+5}&$N\R&+5&$MR&+5&$K?5&$ ?5j&$FX /3102#767.5468Gq.6BXM>{V K 8-6Ed"@ @ aY aY ?++_^]10327#"&5467>'";^\o$j7 aR O=;R!+@d"@%UF7teFV7 w  x* /3]]q2]233]3]]]]]]]qqqqq3/9/]10"#>323273#".4632#"%4632#"!7 X/QG=?#U-NF=ID:9DGuJDrDGuV4,p$`|w$HL6/DOdHLeDOm!&'(&+5ms&m!&'+.&+5%&R+ &+5&&R+ &+5Z'(2?5PP'(?5b'+2?5PX'+?55&+q5@ @0/]102#767.546#.'73^>=s-7?͇+C 5M7!#^>=s-7?>"?5M323273#".2#767.546%2 Z0RF<B {\-NF>G6<{j&0=N3%m~!Xry!i<0_rP1+#+7`S+&N&+5`&M&+5.t9& -&+555"9& -&+5556|&R&+5`i& ;&+555}&,N]R&+5&,MR&+5{'2,S',5@ @0/]10.54632#.'73F>4cpXH-3+C `&VdTUa1%h R8X5@ @0/]10.54632>7!#F>4cpXH-3>"?`&VdTUa1%h yD;:B(Q@9HXG W   @H@HP"o"""/]q2/++33]q]2]q210"#>323273#"..54632%2 Z0RF<B {\-NF>:6*XhR?*07BN3%m~!Xry!PWEFY) /4 w+&N&+5w&M'&+5w9& 0&+555w9& 0&+555hX&f%&+5hX&$&+5w&R!&+5w& >&+555?}&<NR &+5?&<MBR &+5'Y<DY'<D'37!#fM  u&XL\X /310.54632>4gr[K0:RCe&Vk[^o9+:H+//10#+V!@   //310#'7'77'+V5555X7777  //339210'7##!'77RJ75}o}7L)  //339210##'7!)T77L}57}JV?;/210!!y/:;/'__    ?3210#&'7!#'7 *  C hg{z_hg{  /3/10#!+ToPN) /3/105!#NTP@  //]210###!V @   /33//]3310###!!!VtP @    /3/]2210!!5!###tVPNP @   ?3322/10#!#!#%GJGq  +a@B))   ))))##?### ##)0@Pp/]3]]/]]]]3]]99//3]]3]]107432#"&432#"&432#"&432#"&Pa`QQ]Pa`QQ]Q``QQ]Pa`QQ]oMRQOOMSPPPMSQOOMRQOO!@  /33/]23103#5!#3###VPPN @  /3/]2210!!!## P?55%Sx<  Q?55;UzO Q?55`9j @  PR?3?39910%373#'#PVzy}SxO Q?55^@T Y"III I   YI I Y Y ?3+?+_^]9/+++_^]9/^]++]++3+_^]310#"&54$32&#"!!!!!! Í_aePF11$71Ѹ9D7㹶{B (.I@&,+$! &&vY@/' !!vY?329+399/932+391073'67#7&'#7.54$?3#&K==I:G`djB<{/RP.|}3> BݓkP V8CF)A@"  sY  ##vY&#vY?3+?3+99/_^]+910"33632&#"67#"$32.?x7B f##9 (NI2)b}T~lwb˨íu"q*aU3M%.;8)%T+/@')@&!!]Y?3+3?339?1023632!654#"!7#7654#"!336LC͞15ӊb^(`b\+b soLhD3{/\nD3{1^#'+g@<'+ * jY"!jY$/o/  ?3?99//]q]333+333333+333939103#3#!###737#73!333'#!#33'#7#Dp!pq!qj0jkq!qp omE1mՁ ZlD3 '# ۔+%5!*8\@25+""+iY""-..*iY.7-    cYcY?3+?3+99_^]]33?3?+9/+910#"'532654&'.54632&#"32654&+ !!2!ǺuHZ6YkNӱb|g3>BAsV''yR_"v59뎅dqAZB7)?;GZ_T3++H&E`oQLyʘ>1H#'+.14w@D.//1-jY($ 4+'#jY2 /o/ ?33?99//]q]3333+333393333+3333393103333333#3#!#!#737#37#37#37##!7#37hc!e!}5!!yV3X6}L+/D-&½bA@' lY ?o/?3?9/]]]q33+339103!37!!#!!#N{1 mh+klσ}3}}PFmP@ iY??+3107!7'%7'%!!!7Da3A'D!V77)C{y5kypxtx)8h@BaY?O (( (p(( ((''*oY'62oY #aY?+??+3?+99//_^]^]+9310#"&'#!>32"32654& #!!32654&#"'>\yEjO,ѺFW &gKa@CR'zTO\Ksre)4n%ε cnANsZEN~^$$'3!,:@**%nY nY#?+/??+99339/9910#"'532654'#7546324&#">hg@A*323#y!X3^XQb!N RSK;uV~k` 2R3JEL"<\ʰT@U?8\9@"29.̥SK/E {\7.@iY@iY ?33+?3+9910&54$?3&'67#!MvayNPXˬ % IOOK-=> ݂.l@ElY  jY  @P `p jY mY?+_^]+?99//_^]^]q3+_^]3+310&+7!!3#!7327!7P+^ ] ".+/}#Z՗G~o'  h"2O@1   p      '/0??99//]q]q339/3]q103254&+#!2#%4$32#"$732$54$#" SY/^Zm+*լ֭ۢQIE^ZƬ֭+*7 (.2O@+2   #..!!%%%%%&1,& ?33?3?99//]]39/3339933?10%#"'53254&'&54632&#"'##3/5 #X6\6{9-ux9fV*,:6GMP_Ry?r1; H~g{3+!$Uʗ@3!#HJ^ @cYcY?+?9/+10!!7!!7!q-/:h1^ k'&{u?5&t')u'?5sCd^D 1@  p /3/]/93310#&'5673!9>HH>9)DH$HDV @   //293105673&'#DH$HDV:=HH=:#d^D 1@    p     /3//]93310&'3#67!59>HH>9#DH$HDV @    //29310%67#&'53+DH$HDV9>HH>9d^D?@%  p /3/3/]39333310#&'5673!&'3#679>HH>99>HH>9)DH$HDDH$HD(@   /2/29333105673&'67#&'5DH$HDDH$HD:=HH=:9>HH>9H0@   /2/2293333310!!5673&'67#&'5 DH$HDDH$HDhPX:=HH=:9>HH>9)}jD`@ //3993103!!^j8^@   /3/29933104>32#4&#"rуwfŠdHP @@&  P_ / ? o  /]3/]3/]3993333105!5!5!d8d7 @  /3/29933103 %! {RVm%?(@Y`/o/]]qq+9/10!!#m#?#@  /3/99310#4632#"'&'&#"}?L3% &!" @/)3 )''#i@  //3993103#"&546323265#9P3## #>/'5)%37/333105! h//93103#בK7@ /2/93310!!#'k7n7@ /3/932105!# )@ //3933103!!n@ //3932105!3  @   ///39333103!!#knn@  ///39332105!3# K7@   /32/9323105!!# kn@   //339323105!3! n (@    ///332933323105!3!!# knn6@ _/]]3_]q/_]33333105!5! BZ@  /2/39933103#3#ّiK K >@!  _ /]]2_]q//_]39333310!!!!#'kkב"7 &@   /33/39933310!###ؑ7nn# B@#   _ /]]2_]q/3/_]399333310!!#!!#iro" :@ _/]]3_]q//_]393323105!5!5!# i)ג(7 "@ /32/399332105!### ݑؑn @@"  _  /]]3_]q/3/_]399332310#!5#!5!ӑtt(F(ޑ <@    _//]3/]]3_]q93333103!!!!k#ב $@   /3/3399333103!!33B%n#n @@"      _/2/]3/]]3_]q993333103!!3!!ّJ%i# 8@  _//]3/]]3_]q93323105!5!5!3 iג) "@ /3/339933210!5!333#ؑn >@!        _/3/]3/]]3_]q99332310!5!3!3!5!#LF B@#  _ ///]]3_]q/_]3933333103!!!!#kk#ב" *@    /3/3/3993333103!!#3#Bnn K L@(   _    /3/3/]]3_]q/_]39933333310#3!!#3!!jr " # >@!  _ ///]]3_]q/_]3933323105!5!5!3# iגK &@   /3/3/3993332105!3#3# 㑑iK#K J@'    _ /3/3/]]3_]q/_]399333323103#3!5!#!5!B㑑tK (ޑ B@#   _   /]]3_]q//_]32932333105!!#5! ki"h7 (@    /322/3993323105!!### ؑnn N@)    _ /]]3_]q/3/_]3339933233310#!5!3!!#!5jtrrBޑ"ؒ @@"  _  //]3/]]33_]q932333105!3!5! BZ# (@   /3/333993323105!333! ؑnn L@(         _  /3/]3/]]33_]q399332333103!!3!5!5!B#oV@-   _  ///]]33_]q3/_]3329333332333105!5!5!3!!!!# ikkג#ב">@      /3/3/333339933333323103!!###!5!33Bؑnnnn d@4  _  /3/3/]]33_]q3/_]333993333332333103!!#!5!3!!#3!5!Bؑtr#ޑ" //3310!!V//3310!!V//3310!!V //9210!!+ //9310!!+ *fw% #'+/37;?CGKOSW[_cgkosw{@"2Jjj#3Kk.FVznn/GW{o6Nff7Og*BZ~rr+C[s :Rbb ;Sc&>^vv'?_wwcsgokcgkk`dh_[WW\XTOSKKLPHC?GG@n?o*Z+[BrCs.^/_FvGwA#&.6>JFF'/7?KG"*2:NBB#+3;OCCG@ PQӸCи@ԯ?<;87{{|4xgkosw3ccdhlpt0`OSW[_/KKLPTX\,H7;?CG+3348<@D(0#'+/' $(,$ #  KH@Ԩx`H00H`x DAGO   L/333/3339//////////33333333333333333333333333333393333333333333333333333333333333333333332333103#73#73#73#73#73#3#73#73#73#73#73#3#73#73#73#73#73#3#73#73#73#73#73#3#73#73#73#73#73#3#%3#73#73#73#%3#3#'3#'3#'3#'3#'3#3#73#73#73#73#73#3#'3#'3#'3#'3#'3#3#73#73#73#73#73#3#73#73#73#73#73#3#73#73#73#73#73#3#3#3#3#3#3#3#3#3#3#3#3#fiiiiiihhffffffffffhhiiiiZiiiiiihhffffffffffhhiiiiZiiiiiihhffffffffhhiiiiffffffhhiiiiiifffffffhhiiiiiffffhhiiiiiifffffffhhiiiiffffffhhiiiiZiiiiiihhffffffiiiiffiiiiffiiiiffiiiiffiiiiiiffbbbbbbbbbbbc^^^^^^^^^^^````````````e^^^^^^^^^^^`aaaaaaaaaaad^^^^^^^^^^^`cccccccccccb\\\\\\\\\\\bccccccccccc^```````````bbbbbbbbbbb%```````````bc^``e^`ad^`cb\bc^`b%`C%IMQUY]aeimquy}  !%)-159=AEIMQAS@zKk h| OoLldi}SsPp`"eWwTt\&a# +P;;Xxؿ)H*99]'A!/L?? ,Q<%D.55 &I+648<@DHH0M@26:>BFFA "E/22@6<@ ؾ RS@  $(,0ֹ:>Gʽɹ59ȹ48+/D*.C%)$( !@ ?| {~ osw <knrv ;jj\`dh[_cg@OSW8KNRV7JJDHCGLP@4 kKKk  ׹;?HKO@ 3"&*./333/339//////////333333333333333333333333333333293333333333333333333333333333333333333332333310!35#35#35#35#35#353353353353353353353#3#3#3#3#3#335335335335#3'#3'#3'#335335335335#373533533535!355#%355##5##5##5#353353353355##5##5##5#35335335335#3'#3'#3'#3#3'#3'#3'#335335#3'#335335#3735355#5##5#353355##5#35335#3'#3#3'#3+jjjjjjjjjjjkjkjkjmkjkjjkkkkkkkkkkkkkkjkjkjmkkkjjjjjjkjkjkjmjjkjkjmkk?kkmkkmjkjkjkkjkjkjmkkmjkjkjkkjkjkjmkkkjjjjjjmmkkkkkkjkjjjjkkjkjjkkjjWjjjjkjjkjjjjkjjkjjjjkkjjjjj!c c"a c!b!`````````````b^^^\`h^^^^^^^^cccccccb^^^^^^^^aaaaaaaa^^^^^^^^^^ccccccccb\\\\\\\\cccccccc^````````bbbbbbb bbbbbbb^^^^cccb^^^^aaaa^^^^^ccccb\\\\cccc^````bbb bbb{Z//9910!!{!!@  /2/3993310!!!7L17}1mh{//9910!!hmh{@  /3/3993310!!!hKPb//3310!!L//9910! XVRZ//910 7L//9910 LRZ//9910Z79e-)@  ! /3/39933104>32#".732>54.#"wx{yy{xwV`bcb`c``dyyyyxyy{b``bcbbbV^R'/7?GOW_gow@X\PhhTl8xx<|(pp,t ``$dHH L@@D0044DLdt|l\ JrvNvvvBz~F~~~2jn6nnZ^^RVVVVV:>>> *..v~n^V>..>V^n~v&f0b@bb"0p&/&?&&&/]]/]9///////32]32]3232q32]32]3293333333333333333333333310#"5432'#"5432#"5432#"5432#"5432#"5432#"5432#"5432#"5432#"5432#"5432#"5432#"5432%#"5432#"5432'#"5432377349947575#3773865567557R75577667377349944976#58856556\677675577667667+557775555885Z557w55763:C558337775555776557737+558#  //99102#"54>jmsoujlw)@  //9933103!32>54.#")wvuwwwvu}Bwwwutww)#'@ $%  //933103!4>32#".'32>54.#")R`babbab`Nwvuwwwvu}B`bb`c``cwwwutwwsbu &@   /33/]3993310#"&546324&#"326bcfdiFIKgFEgcIN_}khfJHfFffFHdhy $0:k@%+ 6+:;<51@) H168833@ H(.""O"_"3"3"  /  /]3/399//]333+3]+29333310#"'4! 4#"32#"&54632#"&54632327#"'ybbZٗ31Z-!!--!!-+!!//!!+LL=`bHgj34V// -- // --# #-S@4( $./)--!O_-&+++@ H++  /  /]/99//+]]]32]3910#"'4! 4&#"326%4&#"326327'#"'bc0!--!0.!//!.bb>KLHgj{ -- // -- //ۺ#Fs;)5p@=3$-%-"') 3 3 67"   $'0*()/3/39/3933333333333333310373#'#5&''7&'#5367'767"32654&BAe;-VL12WXByd+N P)opÉ;'--qt>}`+%* J-d}>^1N =LJŇP'$T@+  ""%& /@/3/]99//]333339333333310.54632!!#!5!"327654&qqwTVhL%Xw{TV;>wBh}VTylFFxUVy>=TVwR,8F@#0',!66,'9:,*3$-$*/3/399/99933333310&'&54763327632".'#"&54632"32654&+ !C=#"&5467>!aFXdP{XZ[Xe`Ga^%%`]ZRw;3C@&'. 45*   .#  //99//]99233]3910)7>5'#"&54672&'&5463267632#".'Fw^69Zs\=e% qtET'iCJt8v_=1op#8wL/yuzs3B'$'ykVb'NKuu2Qi}x6fZy@   /3/99910./.54632>32bZ[K6dV'!XaXoV{eAkswwucVB   //9910&'6J{FT+t}FiRmX;.@  //9/93333103#654&'#"&54632Ll^/9r@k99}M+/dyyw {7-NsB@#      /3/933/9333310#"54632#"&54632%%5_s{N/+ىs9:wJ6.'DeQovt5-Luguf7u@E    !       `//]q/9///99933333333333310##57573%377```J`X=@`^``F\^` Z :@kY kY  iY??+9/39/3+3+3107#73!!!!!!!#7!%l2m3%1%)6a%wǰC@' `Y `Y?      ??9/]39/]]q3+3+3103#!#737#73!3!%hh%!%w-w%7𬛬1Ϭb@>Y8H  o   @&  iY?+?9/3/3_^]_]]]^]2]]]]2/103&#"#>32!3273#"'!5D" t|2E& qC6kPTm5Q@1 lY  iY 0P`@  iY ??+9/_^]q+39/3+310!#!#73!23#32654&+֜mϽ)Mb)}aa n֘{t]W$.@iY$iY oY #?+?+?9/+910327#"&547!2!'32654&+ݏT;3!l5 OgBN_fJ1\R ~261Ş71ruRRV$4@ ]Y   ]Y "??+????9+9910#&5463233#7##72>=''#"퇐`FzCM} D{Ijhg)J t^V4@]Y cY "??33+33??33+910&547#?3333#67#y sĄ1j 21;YaOV*2>TJf /j;5V%o&@ ]YcY/?+???+910%3!#654#"!!3>32V‰l\+bJ-'*A>dD3{1M]Ik5V"@   iY"??+??39103!#!!7!\G}m52i LPF>D%o$@  cY?/?+9??10!3!#!!3XVLxJJ- % ^yHJ9v,V '@ iY  iY"??+9?+910!!7!!!;]R& 5)TVo^ &@ ]Y  ]Y/?+9?+910!!7!7!!V#?s3+oS{#'@  iYiY?+?+99??10"5$3237!#'#267>5#"Po>FKt+6 xtz!]jJSL%k](fs@ dY ??9?+103!367>32&#"'- ;AgYS:%3X/^b;mx fcV3'!@$iY   ?3?3993?+10)47#!!3>7!37>32&#"`4=-!Q q Y$CnRR7$0F0B^Z145]3~U ]p}s&"@"dY   ?3??993>+10!47#!!3>7!36?>32&#"Z Z3 DH ABbQmCW90N.@^с,=hĎկ VaDs%P@/D     aY   `Yo  ??3?9/]+99_^]+99_^]_]10%367!!#727&54632">54&+H)DoTj%E:n}9#%';R n8kl:r9+6Qa3&5#@ iY??9/+10!!!!52yw#j^!@cY" I??9/+]3+10!!!!7}b0]3^RZs @cY ]Y?+3?+?10 $547>32'>54#"ԭvTDn/̯κ[fQ^Y(H|juҼ݃!/10'%'JII)IImmml /9/310##"&54632PF;9JJ9;F[?==?>+5%}s @ }Y}Y?+9/+104632#"&4632#"&%m`DQmYJRo^DQlZIS \kLFVlL\kMEUmJ/\@YY/]+9/+107!7!/0--{ ?9/10#!T/ ?9/10#/R@ X@<7@H  & 6   `po 0/3]q]q3]]]]3/+9/]1067!#4632#"%4632#"}TqE/bJDrDGuID:9DHt^4FHLeDOdHL6/DOF Z@> H@H  & 6   `po 0/3]q]q3]]]]3/+9/+10#.'5!4632#"%4632#"eg! Y$JDrDGuID:9DHtbz9mHLeDOdHL6/DO-7 $@iY iY"?+9?+9107! !7! 3cX+5#2%7hhH@ I8/2]]106$%"hmefyH@ I8/2]]10 #&%5/k3tH{ @ H8 /22]+310.#"#>32ͣHHs-ݒqY(;6" @ H7  /33]+31032673#"&'JHp/ݔm[%86! $@ /3/99993310!#!5!3d+\+ $@ /3/99993310!#!5!3d+%F $@ /3/99993310!#!5!3n!ZZ @  /3/999310!#!5!3n!DN @ /3/999310!# 7 3g\=H`3R "@ /3/9/3993310!#!7!3bH3o`RN @  /3/99993310!#73^J^sN @  /3/99993310!#5 73gRۇjh0hF@  /3/999310!# 73qZyfkFq @  /3/99993310!#73q_ZGd)5 @ /3/999310!# 7 3RkGHyN!5 "@ /3/9993310!# 7 3Rk`/L-!P "@ /3/9/3993310!#!7!3ysdH^- @  /3/99993310!# 73`wcFFH@ /3/999310!#73vq=Df-q @  /3/99993310!#73qFsGVH!% @ /3/999310!# 7 3>{GHZ1#% #@ /3/9993310!# 7 533X3'5g% #@ /3/9993310!# 7 3D{rVJ1}q' "@ /3/9/3993310!#!7!3by R1X/@  /3/999310!# 73HՇH7%q @  /3/99993310!#573q>{G\1# @  /3/39999310!# 7 36}MH)R/) $@ /3/39993310!# 7 530XAuP/j5 $@ /3/39993310!# 7 3NN-qT+o5 $@ /3/39993310!# 7%3Nu7T+}/@  /3/399310)733+NT-)q@ /3/999310!#73qB=T-)P@  /3/999310!#!'!`sboL #@ /3/9993310!# ' 3\H6fy3L #@ /3/9993310!# ' 3VH)hy?L #@ /3/9993310!#5' 3THhy-^ @ /3/999310!#' 3P5fy=Lq@ //9999310!#'3q^hy"@ //9/3999310!#!5!3qT; &@ //9/399993310!#!5!3`/h{T &@ //9/399993310!#!5!35%"@ //9/3999310!#!5!3@P@ //999310!# 7 3i``ybVL "@ //9993310!# 7 3e`;H`FF $@ //9/39993310!#!7!3gb+\t]^L @ //9993310!#73^'ezL@  //9999310!# 73e\هseRdZLq @ //9993310!#73qe^=ddZ/@ //999310!# 7 3Hu7T`H?9 "@ //9993310!# 7 53Ru9HpHF? "@ //9993310!# 7 3Mw\sX=T9H? $@ //9/39993310!#!7!3lwo V=1?@  //9999310!# 73\w߇5:=?q @ //9993310!#73qXw1-B=+5 @ //3999310!# 7 3N}5H)1q5 #@ //39993310!# 7 53N}<Au1]j5 #@ //39993310!# 7 3NN-q -+o5 #@ //39993310!# 7%3Nu7 -5@  //3999310)7331N߇ -P5q@ //9999310!#73qN3 -yL@  /3/999310!#!'!nwJ{L #@ /3/9993310!# ' 3nH J{3L #@ /3/9993310!# ' 3nH)T?J{?L #@ /3/9993310!#5 ' 3nHu^J{-L @ /3/999310!# ' 3n5RjJ{=hq@ //9999310!#'3qo;L{L@ //9999310!#'3kNf{F $@ //9/39993310!#!'!3bj\L "@ //9993310!# ' 3\H5gyFL "@ //9993310!# ' 3VHiyPL@ //999310!#' 3ifrq\%Lq @ //9993310!#'53q^g"@ //9/3999310!#!5!3XV9ZB^ &@ //9/399993310!#!5!3cf)9% &@ //9/399993310!#!5!3b-%w"@ //9/3999310!#!5!3ZV@ //999310!# 73f^ q%^`V "@ //9993310!# 7 53o^h^xX "@ //9993310!# 7 3q\3Hmg1ZV $@ //9/39993310!#!7!3bL+Vm\V@ //9999310!#73'^{^\q @ //9993310!#73qu\/3g7 @ //3999310!# 7 3=q+\=LD7 #@ //39993310!# 7 53Po+^-L i7 #@ //39993310!# 7 3Po?J?LL)7 #@ //39993310!# 7 3PqX/XLBb7@  //3999310)7331PqLb7q@ //9999310!#73qPq?L{H@  /3/999310!##'!y\1F #@ /3/9993310!# ' 3{Ny1PF #@ /3/9993310!# ' 3{Hb1F #@ /3/9993310!#5 ' 3{HtD1\F @ /3/999310!# ' 3{HX1)Fq@ //9999310!#'3q{91@  //9999310!#' 3wbL^=5 $@ //9/39993310!##'!3ws;s=9 "@ //9993310!# ' 3uHXqHETJ9 "@ //9993310!#5 ' 3uHHG}9@ //999310!# ' 3uHHG9q @ //9993310!#'53qw>K@  //9999310!#' 3[VHZdbVs @ //9993310 '53#/[{b $@ //9/39993310!#!'!3[HVbk^ "@ //9993310!# ' 3[VHB1by@ //999310!#' 3_VHLdy}Lq @ //9993310!#'3q^d+"@ //9/3999310!#!5!3LR= &@ //9/399993310!#!5!3aNA%1o5 &@ //9/399993310!#!5!3qÇ"@ //9/3999310!5!3#d+VL @ //3999310!# 73e\-yfL #@ //39993310!# 753e\ }VyfL #@ //39993310!# 7 3e\j?yf)L #@ //39993310!# 7 3e\=J3yf6P@  //3999310)7!31i\y whPq@ //9999310!#73qi\;wh/@  /3/399310!##'!l-T5 $@ /3/39993310!#%' 3H{-T75 $@ /3/39993310!# ' 3HJ-T+ $@ /3/39993310!#5 ' 3H/P% @  /3/39999310!# ' 3}H)/R))q@ //3999310!#'3qÁ)-T/@  //3999310!#' 3TH7H' "@ //39/3993310!##'!3eyT19% #@ //39993310!# ' 3{Nq}1JV% #@ //39993310!#5 ' 33h5@% @ //3999310!# ' 3{H#1Z%q @  //399993310!#'53q{Šy1H@ //3999310!#'3vfD=- @  //399993310!#' 3mwbFFcP "@ //39/3993310!#!'!3sXdH^5 #@ //39993310!# ' 3kL!-L5 @ //3999310!# ' 3kL!Ny-q @  //399993310!#'3qs!HVF@  //3999310!#' 3RZZjfyN @  //399993310!#' 53LRHh0hjN @  //399993310!#'3}^s^JR "@ //39/3993310!#!'!3bqlV`sN @ //3999310!# ' 3\H3`Fq @  //399993310!#'3qZ)d @  //3999310!#!5!3D $@ //399993310!#!5!53'ه) $@ //399993310!#!5!3sD $@ //399993310!#!5!33\+Շ\Z&~ ? 3&+555Z&~ @ 3&+555Z&~ A K&+555Z&~ B M&+555ZS&~ W 3&+555ZS&~ V 3&+555ZS&~ U 3&+555ZS&~ T 3&+555`(& ? &+555`~& @ &+555`(& A ,&+555`|& B .&+555`:S& W &+555`|S& V &+555`:S& U &+555`gS& T &+555w!& ? &+555w!& @ &+555w!& A /&+555w!& B 1&+555wS& W &+555wS& V &+555wS& U &+555wS& T &+555`]& S'&+5555`]& R'&+5555`~& Q9&+5555`~& P#&+5555w& S*&+5555w& R*&+5555w& Q<&+5555w& P&&+55555R!$@ iYiY"?+???+910"'53267654#"!!3>32_[UOc{-5q{4RyHF9)tد?[{5R $8@   iY iY ??+?+99//_^]9104#"!!3>32!"$547!3 6`6ϡq{Z9-  APtد?[XL@>=1yO{.7@"!"!]Y" I" I"")]Y]Y?+?+9/+++910#"&5467>3232654&+732654&#"`k5PVftg/37!#'u>=s-7?>"?hXM5cpXH-3b'u-'VdUUa1%i nY@9 @ H@14H@@@H@ HVfvG@&%(HD%5vGg/3]]]qqqq+rr++qr++]/3322910.54632>7!#!!>4cpXH-3>"?'u-'VdUUa1%i xD;:B>w! H@. @ @!H @H 6' O _ o  /]q]9/3]]]]/++2104632#"67!#wHA:;BGuNCEB`EK41BQWL.s }@@DH:)2I3I,I$ I@p  /]q]2++++]q2]]]]]9+/39/]q104632#"'3673!&'HAuBGurzzS:yVEJdBQ3|#fQio @ ?O I@ I6'D 5 &    @ I 3 I 2 I ; I @H7gw/]q3]]q+qq++++]qqqq22]]_]++3/3_]2910!!4632#"%4632#"'tROG{HL}{OG{IK}yHKdDOdHKdDOs *@e @#0"@08k{ZI /?OO_o@#&H@"   &/33]]2]]2+]qr22]]]]]q3/9/104632#"%4632#""#>323273#".OG{HL}{OG{HL}&4 ~V/K@7?!}S-G=6RHKdDOdHKdDO5%rz#[}o"G,=@w UH@+ H@x w  /]q33]]]2]]2+]+10"#>323273#".767!#&3 ~U/K@8?!9,H=6D9,b15%rz#["۝c-@Z  S@&$4    @H  g w  /3]]q+qqq_]]]]10#.'5!!!D&,a''u=?qdw S@&  $ 4      @H  g w  /3]]q+qqq_]]]]10767!#!!90:+t&t>H,OKy "@Z  H  E6% `  0  vg5& /33]]]]]]]3]]]]qr29/9/333]]]]3]+104632#"%4632#"3673!&'yNG=>HK}{NG=>HK}E`QIPd/HL50DOdHL50DOC2ei.N|m h@ O  @ IF'7'7gwI@I/I-IG /33]3+++]+2]qq/+3/]9104632#"%4632#"!!OG=>HL}{OG=>HL}'t/HL50DOdHL50DO ]@Dx  F'7@PO_o>/w/33]]]]]q2qq]2]]210!!"#>323273#".'u'3 ~V/K@7?!9-G>5׾5%rz#["Z =@ F ' 7 ' 7  @I _ o  G/3]]+2]qq/33104632#"!!IB89r}'u/HL6/ ) 5@! I ( 8 h x  &IO  x/3]]]+2]qq/33104632#"!!sJBps}'tHKd  (@%'(/(?(((@&O  &@L I"/((@H(((pfvWoo  VG&/33]]]]3]]q2]]q]29/]+q/+3]]3/]3]]9/9/]3104632#"%4632#" 33273673#NG{HK}{NG{HK}ѓTVB"3qG}HKdDPeHKdDP!RYQ3 0)@@&%%%O  &@M I#VG&/@HpfvWo o    (/3]]q2]]q]29/]+q3]]]]3/+3]]3/]3]]9/9/310.'53%#"&533274632#"%4632#"h2f8"џTVBNG{HK}{NG{HK}.w0jhNYQHKdDPeHKdDP  @ O @: IFVv7  / ?  @H  gwOo /3]q2]]+q3]]3/+33]3/]339/]]]310!!4632#"%4632#"673#?'u%NG{HK}{NG{HK}RG]"I}HKdDPeHKdDPBK&0  y@ O @: IFVv7 /?@HgwOo /3]q2]]+q3]]3/+333/]339/310!!4632#"%4632#".'53?'u%NG{HK}{NG{HK} 2f<HKdDPeHKdDP/.w0cp? &r@N%@H @ H  @ H &?&&&o&&@H& /&  f G W  /3]]qq]q2+]q9/+/+9/+310#"&533267%.5463267!#"țWVQm$>5cpXH-3@,%@7-,8&VdTUa0&h y?B? %%@[ H%E!U!!&!6!!! @ H "@ H"?o@H /&  f G W  /3]]qq]q2+]q9/+/+9/]]]2+10#"&533267%.54632#&'73"țWVQm$>5enWH-4d7-,8&VdTUa0&h f? $l@I# @ H @ H$?$$$o$$@H$ /&  f G W  /3]]qq]q2+]q9/+/+9/310#"&5332672#767&546>7!#"țWVQm$>=se@>n|7-,8M=rd?͇>2 7-,8M!!1u@OP?5/ATPiGkXu?'+ s$9@"!]Y dY ?+?+9933??3910"#"'53267>32!!!&+CZJH#C[`Y<%/2O&fpgwrb-}߃$}?gNio/u9NV=:5;9@  iY P `  iY  ??3?+9/_^]99+310 ! !!#!!232654+=X ӧVm5Rd8J+ts&4@   !]Y ]Y?+???+93??102!!#"&'#!336"32>54-b-FSx3 HV :JyMJACzKs}JYJwP`uk@iY  iYiYI I@%I' I I I    iY ?+??99//_^]+++]+++++9+310!!!!!#!.54$)#";D8#P5wuakY3m^l1DkroO[s1:C@A AbYAͲIADzIA@YIA"HAAD """995222 2cY5&bY?5555 5 55;cY dY /++ +cY?+_^]3?+?+?9/_^]_]_]r9++_^]93_]9/+++++_^]910"&57#"#"'53267>7&5463!632!#3267"32654";}>9R.Bo[<(%*5:O5t3f`We]5Y.#O]FM];Odt-"`NA?T[i&0.(saS_WI7C5@     ?3?39107!'!!!'7XnZ52-rad1T\d%!^@     ?3?39107!'!!!'7TuXhRRu.ocyiV!^h,5@iY++iY+ %iY  iY #?3+??+?+9/+10632#"'3254&#"!! #"'532>! PXvؾ{ȑI6uOP?5/ATPiG]13 ӥ u?' ^s5B@$.",,*2]Y]Y2%*dY% dY ?3+??+?9/++993310632#"&'32654&#"!&#"#"'53267>32^3PʒA'b{YW/#PӼ(CZJH#C[`Y<%/2O&fpWEo6ؼqzu?gNio/u95#H@.iY iY I ) I  I  I I  " iY #?3+?3?399//+++++++10632#"'3254&#"!!!!!!PXvؾ}ʑI6uӆ)52yy113ץ w=% `^#L@0]Y cY # I "I "H " I    " dY ?3+?3?399//_^]++++++10632#"&'32654&#"!!!!!!`3PʒA'b{YW-%P`b0]]Z-o6ؼqz3^R5V @ "iY oY ?+?+??10!!!!!!3350\L@`%os&@ ]YdY/?+???+910%!!654#"!33632^l\+b ΊPuD3{1^䧛Ik}5V#@ iY oY"??+??9/+10%!!654#"!!632\m 52w =`.$JqV5@%o&@ dY]Y???+/?+9104#"!!3>323!!6=l\+bJ-'*A>dP^{1M]Ik}uD G@3  i y X  0/   /   p   /]q33]q]]]q210#'##'##'7sEEFEF'XggggXDC@(    sY ??+?9/////9910%>7!!"&'??!%%8M;%%'N:o%n% j1111^ffdg`G@LG.L@l\$BG/@l$G0@G@#G@ ^ ^ v V 0  ** DT * ( \ >F <  4VCopyright 2012 Google Inc. All Rights Reserved.Noto Sans UIBold ItalicMonotype Imaging - Noto Sans UI Bold ItalicNoto Sans UI Bold ItalicVersion 1.06NotoSansUI-BoldItalicNoto is a trademark of Google Inc.Monotype Imaging Inc.Monotype Design TeamData hinted. Designed by Monotype design team.http://www.google.com/get/noto/http://www.monotype.com/studioThis Font Software is licensed under the SIL Open Font License, Version 1.1. This Font Software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the SIL Open Font License for the specific language, permissions and limitations governing your use of this Font Software.http://scripts.sil.org/OFLff  34566778:;YZ[\_`ders}~NOGHTU > ? W X o 45Z[  `bddss!#$$%%&()+,-/1256689::BNHIJJKQRRSSTT Ncyrlgrek$latn4 kern8kern>kernDmarkJmarkPmarkfmkmk|mkmkmkmk        *:JZjz  * + . 0 E V W d e i  lm dF`bddss  %(3!-:/6G8:OBNRHT_%$=D]4KBj77NNSV\_27 BI^alq~!WYZkl""(UZW]f]kngqk{QQbhssvvl   $*06<BHNTZ```flrxxxxxx~xxx~~~~xxx  xf f~~x~~JPV\bhntzP "(.4:@FbL4:RXb^dPjptv| $*06<BHNTZ`fZ`lrx~`fTT &,28>DJbVJbVJbVPbVPbVVbV\bhntntttz.:@:@:@:@:@4:@|||| ****ZfZ"fZ(f."f4:@FLTRXRXRXR^XFTFTFTdTj2j2pvV|JVJP    bb**P *P*$B*0B6$B<BBHNTHNTTZZf`f"flZrfx~`f$~rlx ~P fP`P fP `P `(. T"(&,2(. :T8>D"(JPV:@\Xb@hXn@tzt^Xbr^ jjdPj pt pbFLT"(T.FT4:@FTL >TvR,Xb^d jpv2|pDDD   j2lZlJP 4L$v|*TJP0 6<BVHNTZ`flrx~fZ`4:X@v|*T2: N2j2pt&,24t8>DJ2PPV\bhnxtz |>J$x$VTNVPl~~f ""P4:@(.4:@FL2bXbRdXj^dDjpv|,pt\hV,X28DPb $*|06<BHNTZ`flrx~VZf@RFTh:B:B~4V\ &,28>DJPVh\Bbhntz(.FTVVZfZ"fb@ b@RX^^ F*TF*Tv *|.T"tB(.4:@FLR8XJxV^dj:@Rpv2| p^8 h   \bhv| $b * 0P 6 <Z`l B H N TXt^r,2 Z `  f l r x ~X  `       lBB    * H:TH:PZ`f !!!!!! !&!,!2`!8!>!D!J!P!P!VPP!\L!b!h!n!t!z!!!:!!!!!!!!r!r!!!!!!! !l!l!!!!l!,*T"\" !\"Z! "X" 8""8"(". ,". ,"4":"4"@"F"L"R"X x"^4:@"d"j"p"v"|!"`"Z`l"""""4":"4@"""""""""""""""""### #L##:" #$h#*h#0#6#<#6#<P0#B<#HTr!#N8D#TB#Z#`#f#l#r#x#~###f##!#"" P####B##rx#`##H#6# x###!d#&#8####  6$$$"$Z$$ $&r$,$2$8$>$D$JbhP\b$P$V$\\b$b$h$V$n$t$z$#$$$$T$` 6T$` 6$$$<$$B$$T$HN$$T$HN$HN$z$Z`$$$%~% t%%T%% t%"%T%(%.`%4%:%@%F%L`%R%X`%^%d!n%j%p!n%v(. T"(%|6"(%%"(%%%tL%%tL2b^%Xb%%Xb%%Pj%dP%%tj%%%j%%%D%%&t&& pt&r&pt&r&$pt&*r&0v|&6*&<v|&B*&Hv|&N*&T&Z%&`&fX&l &r&x&~&&&&2&&D&8X&8&H%&&& &&2&N&&<&&&& `f FbLXb&$LB& ,''8''YmEj 9$vB~V`\2( (dttL2dt~~~L~{L{S~+ SFt<qqpp \F\m2mBB%t%%Labhb\Sah hkhk0@l0xh$F0/W& H9 r'Ll0:sqqll-lPlljLka@aatxA@};@;l 0O@tOk@W@Wk@a$,B<n,l{;{~,8{l;,<;2 a,,l<aT@400, $20,2 XInnL<h<Fh<0h<pOOh-k,<<77n0/<,/@,/,DK, <<,GB,H`>8h>HT0k,kLx`<',~j,jla,,\h\l'@rl'BR@Ga%G4/4 LaLP+4;4+ ~;P;+~ H0P.444W%4 <WP4k94 kP4B b,P^^\,76@&c4h ,:x,DJ,JiX>X`. 8w,,[h[Nh  e(99<<S$ ,C@ `W@p}@ohxLpU@=@h+,,((,$,I} %@,%9S@"n CXH\j1j,`g,.\,,W,,@p,,'EP,h442V0Ehh..,,sS,p$ >gg+;ppUUbzda&rKDf:[Mx)0ehhXh h^|Ox3h;hKGssh9Rhn9>opapp ~f,0ak4lklK}4LpptF@t~4FhF4tF44040Xpp,54O449p9pb@,p4444@G4LGl4Hl 44ppMp/ppCp 44b44lal@4'rdLdaR,p*,( Pb`aHHNTHNTZ`flrx~Z<l}/lkqTzGfPoTD $=D]4;CHNOPQ?ARCCUGGVJKWMMYSSZWW[YY\de]xy_{{ab & ,28>DJPV\bhntz\bbb\\\\\\\tttt\b uLHuTlLZtxJbN^8z-_^^(Ls4^^b^^"^^P^BHLLL^b^J^^^ X^ $=D]4679;<*+>FI@^aDH "(.4:.@(FLLRX^Fd.(jpv|dddddxVx4* xdxxyG,NtHb^\#M^^`n8s%(Lv^^J^^f^@^ ;A$=D]4KBj77NNSV\_q~]""eU&QQ'bh(ss/vv0   1      & , 2 8 > D J P V \ b h n t z &  " (.4: @FLRLRX^LRdj@Fpv |@F &            J J J J                   $"(.(.(.(.LRLRLRLR*0@Fpvpvpvpvpvpv@F@F@F@F      " " " "     (. (. (.  (. (.6 2 6 2 6 2 , 2 < >BF 8 >@F JLR JLR JLR D JLR JLRHNT Z VLR \ bX^X^` nfR h nLR h nLR h nlr h nx~ @F @F @F @F pv pv pv | | |     & & & @F @F @F @F @F @F          LRLR zdj                           (. (. (.  .  .  . &. (. JLR D JLR pv pv ,v ,v ,v 2v pv8888 @F @F>>>>    & DJPV  "  \bDJ   hntz &6 2  D J D J \ bX^LR @F   &   "(.4:@FLRX^dj pv   JLR pv @F(.$ , 2 6 2 | b^ pv pv@FLR6 2  @F     (. (. JLR JLR pv pv | | @F @Ftz< >BF     (. pv   " h n & $  (. P VLR*0 | 6< "BH  NT(.Z`flrx~LR  @F@F@FLRLRdjdjdj@F@Fpv||||| pvpvLRLR&,LR@F28>D  JP V\bhLRX^nt z28  4:dj@F| LR28 X^LRdj@F|  &   (.flrxLR"LR@F""    "           &. &.  (.  (. (. &(:6 2 < >BF 8 >@F< >BF 8 >@F 8 >@F D JLR JfR| b^ \ bX^ \ bX^ h nLR` nfR h nLR h nLR zdj t zdj @F @F @F @F 2v 2v 2v 2v. .  | | | |      &4 & & & @F @F @F BF BF:    @ &@ &    @F4FL RX^ h nLR h n  djpv<J-J(NjjVV??%%    ==''JJuu``==^^HHNN''0)0)0V00j0 0000FF000,0%0`0yy550=0?0'0J0hh 0--%%33h0uhu0h0-030!!LLHHRR##XXwwqqHH 0   ddjj00q0``  ))mmRRffLL11BB^^))\\ffqq33uu%%LL//!!HH000H000Nh'h0PP $=D]4KBj77NNSV\_q~]""eU&QQ'bh(ss/vv0   1      & , & 2 8 > D J P V \ b h n b t z b h b     & & & & & & > > > > V P b b b b b b n t t t t h b b b n n n n b b t t t t t b b b b      b        & & & 2 2 2 8 8 8 8 > > > > > > J V V \ \ \   J J J V  b    " b b b b b b b b b b b b t t t t t t t t   & & & & & & &           > >  "  "  "  "  " V V V h & ( h . D n 4 ( b b : @ D F    L R & X ^ d h 2 8 j p v |   \      h      b X  b  & > t b b  & &      b   b b t t   & & 2 2 > > @   b   \ b t & V    ^ ^ n    >  t   b 2 V  b h h n  b b $ t * 0 6 < B b b H N T Z  ` f l r x ~      \        &  B H   b            2 2 h b z h  b  N  T h   h b  h  b b b t 0 6  n  h h h n b b b b b t t t t t z b            & & & & , h , h 2 2 2 2 8 8 8 8 8 > > > > > D D J J P P V \ \ \ b   b   , 2 b   J0000j0V0?000000%0 0 0000=000'000J0000u000`00=00^00H00N0'00)0F0000y0005000h0-0%03000!0L0H00R0000#00X00000w0q0H00 0 0d000j0`0 00)0m0000R00f000000L00010B000^000)00\00f0000q00300000u0%0L0/000!00000H0000P00 Z`"$&(*,./125678DFHJLNOQRUVWXL"LRX^djpv|dS t1Ab4XD $=D]4KBj77NNSV\_q~]""eU&QQ'bh(ss/vv0j1jpv| $*0$6<B$HNTZ`fljjjjjjrx|~$$$$ffjjvvvv| | $$$$*$$$$Z$$HHHNNZflllZZZf**6jjjjjjjjjjjjj$ &,2,8,>DDJfffPV\pbvh|n tzlH$T<hNlN<     " ( .j$ 4r : @ F @ L R   X<jj ^ ^$$$$ d j p v |j f N jvh p ^* p$fh h TTTh * P d  $      $ * 0 0x< 6 < B HT N T T Z ` fP ll~ r x ~    * x     6<$$HNl   $ &< , 2 8 > D 2< > J P V \ b b h 2 2 n t z > np  |   F L  $ 66  <<$   H " (HH " (N . 4 : @ F L R X ^ dT j pZZ``fll v | NZf$Nh z SX4pE\ HHHclLHHHH$OppHp p'?pp HbpHpplppXpp0HHpXH0HR,HHtP!3HvH5H*^Hm Uk%HMHI HHppp ANHHHp/H&H9H&~H HN8aHHRHHE+H~HHDHHJ>G8-HRc7 EHHH%H4HXLpH@< Hpppp pppplbp4\ HRpv4 6@EGIKMQSZ ]]4:6<BHNTZ`flT6rfx~jdjpjJjj\jhjOjqjjjbjjj p`bss!#%% )+!/1$66'::(BN)HI6KQ8SS?`bss!#%% )+!/1$66'::(BN)HI6KQ8SS?@ &,28,>DDDDDDDDDDDDDJJP    VV\@``flrxx~  &  ,28    >>DJPJJJJ~((lOFt(`(`F2(t`xT<22hTPxh hhZxPhhT(nxhhhd|nxx0PTPxdxxdFdZdP@Z@2dFF|d@x@ djdd  $$&(,- 25"89&JJ(RR)TT*dd  $$&(,- 25"89&JJ(RR)TT*+    $*06<B HNNNTZ`f6*BBlrx666666* + $*06<BHNTZ`~t`tV a`24` 4 26fl$$*D)`dos""PEKNO<-2"FEKNOFtsdtdpqtod    xzz    d<< n t t *0b ndvvdddvv n *****ddddddvvvvvvvv6vv d d dH*v*v*v*v*vdHd*bbb d*f t6f f!^!hf!~ !!h! t!d!!"".d"d!"v"""""""6"#<$&&#<#<#<''())$)')'**&$'+|'))#<#<**d,Vdd,V,\,-8,-8-R,,\dd-|-|,,d-8d-|-|-8,\-R$. << t< t t. d..d*-R/6-|&(/(/1212),V1<*,'-R'-R-R-R*,*,*-R&)d/6-|*,1345 56),V56',\',\',\)d1.65 74,&$d7n9p7n9p56)d)d95 :<d:<d':^,\)d)d)d(d(ddd*,*,'),V-8*,*,*,*,'-R'-R'-R$.1356'6:;:;)d:;:;DFHIKKNNPS UU$WW%Y\&^^*+78=DJNORST^_`adnostwxyz{|}~$(**,,..0022446;==??CEGGVV[bddffhimmooqvxy{|~~      !! PQ UV]]__ggimosuuwy{!0O[abfhjnouxAFJLLNNPPRRUUWWYY[[]^cceeggiikq~// $79:< DFGHJPQRSTUVX  !$&+-/13568 : CDFHJV_biyz{~ TUV]_ghnoprvz|  !"#$%&'()*+,-./013579;=?AGIKOQSUWY[]_acegikl n p ~-Z&*24789:<$&*,.02468:GfmqrsuxQ\^iy{}    FHJLNPRTVXZ\^`bdfhjlnp~7$&q~< &*-2479:<$&68:G \FHJLNPRTVXZ\lnp~4$79:;<=$&68:;=?C U "$&(*,.0lnp~%&*24G\FHJLNPRTVXZ\-<$C U "$&(*,.0N &*24789:<$&*,.02468:G \^FHJLNPRTVXZ\^`bdfhjlnp~!~~$;=;=?C~ ~U "$&(*,.0"$&*247DFGHJPQRSTUVXYZ\] !$&+-/1357<>@CDFGHJ TUV\]_ !"#$%&'()*+,-./013579;=?AFGHIJKLNOPQRSTUVWXYZ[\]_acegikm~$C U "$&(*,.0"$&*24DFGHJPQRSTUVX !+-/135CDFGHJ TUV\]_ !"#$%&'()*+,-./013579;=?AFGHIJKLNOPQRSTUVWXYZ[\]_acegik"$&*24DFGHJPQRSTUVX] !+-/135<>@CDFGHJ TUV\]_ !"#$%&'()*+,-./013579;=?AFGHIJKLNOPQRSTUVWXYZ[\]_acegik%&*24G\FHJLNPRTVXZ\   YZ\]7<>@ m  < << <5FGHRTH]3579;=?AGIKOQSUWY[]W( (DFGHJRTDFH( (V]!#%')+-/13579;=?AGIKOQSUWY[] ( ("( (   ( ( F@F`F( (  fmqrsux QV_bdipqrtux Q%V_bfimsvyz{|}~ !qrxQV_bi -V_bfimsvyz{|}~ !Pfmfms~~V_bi~ ~ V_birx Q V_bfim    y~ y~ y~    y~ 4  ky}     ghijnoprtvxz{|~   i{    #iy{  N22 giop{|22 -  ky}      oy  }    < opwy}   ~~~ ~ops6 opw}  g|          p!  j~  % gp|  I(W(Y2Z2\22%('(72224(5(Z([(m2(I2W2Y2Z2\22%2'272224252Z2[2m22  y}  b  ghjnrvz|~      op ghinoprtvxz{|   % gj2p|~222 #  y}      j~  !i{  gt2|   '  y} t  t }   ghinoprtvz{|     p(  y}    }  '  jy}~    :  osy}         o}    )  oy}   Lcyrlgrek"latn0aalt2ccmp8ccmpBccmpLligaVrtlm\rtlmbrtlmh 0@P`ph< T"*2:BJRZbjpx&.6<DLT\djrz^fnv~ (0 $*2:BJRX`hpx$,4<DLRZbj                           LMW`bss!#%% )+!/1$66'::(BN)HI6KQ8SS? (B~FPZdnx  (2<FP ` a ` a ` a !` "a #` $a %` &a '` (a )` *a 3` 4a 5` 6a +` ,a -` .a /` 0a 1` 2a 7` 8a 9` :a Y G k l m j n o '*,./0I 4L5OZIL[IO  ; < = > V 7LMWlinphone-desktop-4.2.5/linphone-app/assets/fonts/NotoSans-hinted/NotoSansUI-Italic.ttf000066400000000000000000010401501376717241300310070ustar00rootroot00000000000000GDEF3d(GPOS`$GSUBF #7 `OS/2R`cmapO'hcvt }%&8lfpgms-p. gasp#tglyf1e_H.head[z6hhea=]T$hmtx%loca솘9%maxp x name4post]fT prepPx6j\I_< 4(   !%  o pRTh\Kt33f  GOOGX J )#+=hFdbBRRRbhh} 5 )huh%hh-h hLhhh\h` ) hwh}hwqmTVTTTmqV/TTRRTT 'jj7?RRmhT)Do9b9bbb3997799bb/9u Zqbu?hhshhhh{h7oVh}5%mh}\uo= R~K3[qTTTTVDRhujjjjTbbbbbbbbbbbb9999X9bbbbbh};qqqq??bbbbbbbVTbVDbTbTbTbTbTbm3m3m3m3qV9qT99999!9/T77T7TT7T`7R9R9R9/UR9bbbbT/9T/T/9 'u  'u  'u  'u KZ)jqjqjqjqjqjqu????Dhbbu; 'u ooHoD%ymoNoh B BYW-BDT}hTTT?qVTRR#qTT/7b=9}hbRsH=b9`b}h7bRbNbbfNobb}hbbTdT '/)=TdTqTVTT TTFNTTT1RqVqTT7^R#RR VTuTTb\dTb3bbqq9Z99b9b9?`bqyq%qT/J9Bb93bu 99+999?qT9uuu?555)1d{d{d{{hB') #LVL) h)h7h=7)o7w}^U]Zs h}db#hsh}h}h}ZXVy%TTd{5!qjR9b sh++bq(TTbqhuZT9FT9T^Tm9Nb`` =bb!bhbswPsy))TquT/}TJ T9NR;9R9T7N{T9 T9T9bb9bj7BFZ+m#y#R9!{J!{JFT19H`qT9T9#R9bbbTbJR;JR;FN;yTqTqbbb???#yT9VT57\bbb;T9bNVZu=-VbbbbbbbbbbbbTbTbTbTbTbTbTbTb9bbbbbbbbbbbbjqjqqqqqq??? L RB9\V9bVDbboXJRND=mj9}hT77;9 `b#T 'u/X/ZRZo;??;ND==j!!!) TT1bTT!7RR9b9bjqjqjqjqjq;bbbm 3m3T7bb;y TT1bm3/T R9bbTbTb9bbT/9T/9jqjqNyqV9TbZP?bTbbbbb?V93b3b?u u}JjDT/b//m?hqb99bb%;h;=mb33Xb9\q99}hZ%7qq9/99b}b\`b/N/// -RP9P9uqRf-y\???)Tbm=`b9R9b?!?+bHbbZZ3Zo77#7++sd{{d{d551''H H HHBN551 uoB})XXXXXXXoq)y{#MJ;o' }}}#}#iPM>Bu*qhV=K~?S[;PL`= 0|QDXJ%E!3m!P/!N!h\!fb Rd=P!`bbbTo5ZVbT+;;5 bB7-bbTRjubuF+b;5{9#9J99b ;5Bmb9Jmww7J7{})J;;9 yXD+HH';qFH{yHH-yy??=9yH53}^?(*3^??S9b /uXJ} 9bX3799/u ;bbbbb=;9/q%D 3jj99 VoHFyyHy;hZTmum T9T9T9bVTbVTbVTbVTbVTbTbTbIU;&TbTm3qV9qV9qV9qqV9A9T7T7T7TTTRM R9R9R9R9R9R9bbbbTTT/9T/T/T/[ 'u  'u  'u  'u  'u ZZWjqjWjqjqjqjbjbuu77????9Zu?bDoBbbbbbbbbLXLXLXLXLXLX======v~~99999999v~~ff}h}h}h}h}h}h}h}Uw~wu~u~ffbbbbbbb~bm~yR~LB)3^fbbbbbbbb~~w~wffbb==99}h}hbbbbbbbbbbbbXXXXXX        ZvZ `~ ` `~ ` `f `fbbbbbbbb ~ ~ ! ~ f fbbbbbbbPoNo   9 ii}h}h}Q}Q};}bT}i;7-{bbbbbqsFVXL!Lhyh4N%%?5Ld2hhuh9hm5?X1hhHm hDjRjR>  dh#f{mmb))s+jVFR?;?;fBhfT#{T9T;7?buTy9ob!j3/{yS VjH hVVVVVNVRVNVNVFFV5V5VPV-VH-V%V%V%V'V/%VVV5V5V/)VPVLVLVLV^LVVVVVPVLVFVLVLLV/V9V?V?V??V5V5V5V5V55VLVLVLVLVLhVLVFVLVLVLLVVVVVVVVVXVVVV\V7V7V7V7V77VHVFVFVFVFFVVV9V9V99VVVVVLVVVVVLVLVLVLVPPV/V5V5VV)V/V'V%V%V%%VHV-VPV5V5-VFVNVNVRVNFVVVVbbbbbbbb}h}h}h}h}h}h}h}h}h}h}h}hTR3 3 3 3 db3)3)3)3)3)3)3)3)1T}ZT9DR}9yT9=R9hu"hsh}# \`` ~ac67"#ou~  OP\_'=?EMWY[]}  " & / 0 4 : < > D ^ p y  !!!!"!&!.!N!T!^!!!"""""""")"+"H"a"e###!%%% %%%%%$%,%4%<%l%%%%%%%%%%%%%%%&<&@&B&`&c&f&k&o),m,w.!# bd78#$tz PQ]`>@ HPY[]_  & * 0 2 9 < > D ^ j t  !!!!"!&!.!M!S![!!!"""""""")"+"H"`"d### %%% %%%%%$%,%4%<%P%%%%%%%%%%%%%%%&:&@&B&`&c&e&j&o),`,q. ^IvedAeY @SQzKIzx?wZI we%" {ob`aa` kLP>:6&$&8F0(.@@<"$ IJ$%KLM`abVPQWXYRh X Y Z [ \ ]STUV     ;<=>r i,-03PQ45Z[@G[ZYXUTSRQPONMLKJIHGFEDCBA@?>=<;:9876510/.-,('&%$#"! , `E% Fa#E#aH-, EhD-,E#F` a F`&#HH-,E#F#a ` &a a&#HH-,E#F`@a f`&#HH-,E#F#a@` &a@a&#HH-, <<-, E# D# ZQX# D#Y QX# MD#Y &QX# D#Y!!-, EhD ` EFvhE`D-, C#Ce -, C#C -,(#p(>(#p(E: -, E%EadPQXED!!Y-,I#D-, EC`D-,CCe -, i@a ,b`+ d#da\XaY-,E+)#D)z-,Ee,#DE+#D-,KRXED!!Y-,KQXED!!Y-,%# `#-,%# a#-,%-,CRX!!!!!F#F`F# F`ab# # pE` PXaFY`h:Y-, E%FRKQ[X%F ha%%?#!8!Y-, E%FPX%F ha%%?#!8!Y-,CC -, %EPX ED!!EDY-,!QX d#d b@/+Y`-,!QX d#dUb/+Y`-, d#d@b`#!-,KSX%Id#Ei@ab aj#D#!# 9/Y-,KSX %Idi &%Id#ab aj#D&#D#D& 9# 9//Y-,E#E`#E`#E`#vhb -,H+-, ETX@D E@aD!!Y-,E0/E#Ea``iD-,KQX/#p#B!!Y-,KQX %EiSXD!!Y!!Y-,EC`c`iD-,/ED-,E# E`D-,F#F`F# F`ab# # pE` PXaYh:-,K#QX34 34YDD-,CX&EXdf`d `f X!@YaY#XeY)#D#)!!!!!Y-,CTXKS#KQZX8!!Y!!!!Y-,CX%Ed `f X!@Ya#XeY)#D%% XY%% F%#B<%%%% F%`#B< XY%%)) EeD%%)%% XY%%CH%%%%`CH!Y!!!!!!!-,% F%#B%%EH!!!!-,% %%CH!!!-,E# E P X#e#Y#h @PX!@Y#XeY`D-,KS#KQZX E`D!!Y-,KTX E`D!!Y-,KS#KQZX8!!Y-,!KTX8!!Y-,CTXF+!!!!Y-,CTXG+!!!Y-, T#T[XCPCT[X!!!!H+YCPCT[XH+!!!!YY-, T#T[XCPCT[X!!!I+YCPCT[XI+!!!YY-, #KSKQZX#8!!Y-,%%Ij SX@`8!!Y-,%%Ij QX@a8!!Y-, #Id#SX<!Y-,KRX}zY-,KKTB-,B#Q@SZXB TXC`BY$QX @TXC`B$TX C`BKKRXC`BY@TXC`BY@cTXC`BY@cTXC`BY&QX@cTX@C`BY@cTXC`BYYYYYYCTXBY-,Eh#KQX# E d@PX|Yh`YD-,%%#>#> #eB #B#?#? #eB#B-,CPCT[X!#0Y-,Y+-,-@;k K~5t~~[PZU?ZoZZZOZZZXUYPXUX@XXTUUPTUTVUWPVUVV VUPU_o߉ PMU+M;M MkMMMMNUJPIUIII7IIIIUGPFU`FpFF;FFUOPNU0NNULPUKSPRU?RRPUQPPU!3 U  p   {  U3UX}us0tttt tFs]@-3U3U l04Fl] im>m]-Z&&H&H&&&###3UU3U?b ;aa]9`]0_]5^^$^;^]0]]]]dU3UU3UOUdUoTS++KRK P[%S@QZUZ[XYBK2SX`YKdSX@YKSXBYss++^stu++++st+^s+++s^s^st+++sstt+++++++++tu+s+++ssstu+++s++++s++stu++st^s++^st+^ss++^ss++++s++st+u+st PuH{jF3`5 {n{ 6666zd `T~<v . l > F N LFJ*x(nb88L6X B~r z6`  j !:!""#F#$>$%&%l%&@&'''(h(()F)*+++,-@.<././x/001 1x1223h334B445P5|5566667 7D788889949V9x99:t::::;;B;<<<==:=\=>>>??<?^?@@@@AA(AJAlAABpBBBBCC2CDDDDE E@EFF&FFFhFFFFFGG<G^GGGGGH HHII@I`IIIIJJ&JHJhJJJJKK&KHKjKLLLMM&MHMjMMMMMN N.NPNhN~NNOO0OHOjOOOP<PPPQQQ>Q^QvQRRRRSS8SZTU U,ULUdU|UUUVV$VFV^VvVVVVWW(WX0XRXrXXXXY$YFYjYYYYZZ"ZDZhZZZZ[[2[\4] ^@^b^^^^^_D__`:``aPab@bc&cJc\ccccdd:d`dpddddddeeeff&f6fffggdgtgh,h<hibiiiij j,jPkklmmnrnooopppqqrFrshstTtuPuvtww8wZwzwwwxxxy<yLy\yyz6z{:{\{~{{|V|f|v|}}~B~~ tVfv.^:j&F$D ,<L"<^<\&6ZjN6V,l:\~n<(| @N8XD<jt Fhl,t:xb&t*Bjr.@Rd0Rtp$4Ġ:lȮXhx@r$<T$^ҰӄPԚHՐ׈v4rܪrޒ F^v>.*XJ\ vP` df60F<BP`*J*Np<^n~ .Nr j"NV@Ph   X &  t  ^n :b$Rv"X| 0Z8`Jn4Ld@h0Rr:Rj Bb0Hj>  !H""T"""#$f$v%%&&&'8''(n()*P**+,,-<-.@./F/00122*2:234D556$6678(899~:::;<<<=F=>?L?@J@AxAAB@BPBBBCC.CFC^CvCCCCDD6DVDxDDDE>EdEEFF&F6FvFFFGG8H(IFIhIIIIIJ&JNJpJJJJJKKLTLvLLLMM"MFMjMMMMNN:N^NNNNOO0OROvOOOOPPPQLQ\R RSRSbSSSSTT(TVTzTTTUU(UHUVWpX\YJYZ[n[\D] ]^ ^x_d```ab"bcd8de>efrg$g4gh|hijfkkklllmnoopqqr\rsbttttu|vvVwwwxy$yzz${{{| |z|}^}~2~~x@>\\\X ^BRD8.8N xTdtLz 6b&8rJHn:Z T\J|P"4DVhzN@0b^ 0Tfvp Bn*RtlJ\n4Ft2,`2rV`pr*L**x<ÖzbrŲJ\l $ʆ ˀz͂8ВX~ӂ4Ո4ך؈.&6FVfvR(:JZjz߈j>T:T<4 hBV\:VTpzB"pF\rDf(l@\4 B      "   V r   LjbZH0zzT*RZtL$ p!F"(#*#$.%"%&'P(*()d)*+X+h,H-./001:123N34$45b5r56V6f67P778^89>99:^:;x;P>?2?@H@A A^AB8BCTCDZDEF F\FFGG`GGH,HHHI I"ITIIIIJJ4JLJ~JJJKK@KdKKKLL4L\LLLLMM<M\M~MMMMNN.NDNlNNNOO:O\O~OOOPP*PBPlPPPQ,Q^QQQQQRR.RFRxRRSS<S`SSSST"TFThTTTTUU(U@UjUUUVV:VRVjVVVWW.WNWpWWWWX,X^XXXY Y4YfYYYZZ6ZXZxZZZZ[[[>[`[[[[\ \,\D\\\\\]]>]b]]^T^v^^^^_ _B_d____``@`l````aa@abaaaabbBbdbbbbcc0cRcvcccd d2d\ddddee2eVezeeef f2fXf|fffgg6gXgzgggh h0hVh|hhhii&iHijiiiij&jHjjjjjjkk>kbkkkkllHlrllllmm4mVmxmmmmnn:ndnnno o6o`ooop p:phpppq$qNqxqqqr rJrvrrrs,sZssstt>thtttuuBunuuuv&vXvvvvw w2wRwzwwwxxxdxvxxyXyyyyzz,zNzrzz{{n||*|L|r|||}}$}H}l}~8~~8\~(LpBd2b b&PzJJ2jL@ *vJ0nz@8t$H,6FXfhXH dp6Z0phLl.\FH2zèJzĨVǠLZʄǹF.ϚRx\x0l@׀\غٮrVܖ&^ݦFrަ0߆Vx2h,pVB*t `B.f b<.^RF nhJHlf<2zlZB. bR8(|\L,~ll8:f  `   :   0 x   Z   B  .>d"Hn,Rx0X HPZlb.`. B !"V##$P$%&P'z'(L))*+^+,B,-T-.h.~.....  /2/310!!7!!IhyJh)3"@   }Y ??+9/_^]10 #4632#"&3yTF.:QD58K[96F`:L ?3210#!#sH%sH=;M@- Y Y? O ?O    ?3?399//]]33+3333+3310!!#!#!7!!7!3!3!!! ` {}x c +z}'{'\TTLNNLF3%+,U@. %&&sY@H@+  sY@H.,?99//3+3+399+33+39910#7&'5.546?3&'>54&'11|JU`'$|Cx~\shy@M lm<'14t @A T8 wY6QJqZp4f  *9=@&7`7777o77%00????99//]]10"32654#"&54632%#"32654#"&54632Af?g>fC?fWp{grvz >@d?d?dE=fYq{fsv{F{ugla2|JFzt}fld-B)(4K@(((% ) )0iY%iY??+?+9_^]33999/10!#'#"&5467&546326733267>54&#"qy܂˲e׳MwLetp:gVf߆d=QOfobRf̟SqZh<`rJh{CS`CM[8HYvix ?10#sHR  $??103#RsWD b $??10#3q`'}Vf ??]10%% '%7Xy{o}29q)06}m} '@ ~Y /_/]q3+310!5!3!!#}}{?/?/]10%#67b\o&5=w@ `Y/_/]+107!5%$Ѧ)+ }Y ?+1074632#"&)UI-7RF37NL^76H`8 ??10 #պ-JuF @ sY sY?+?+10#"5$3 "3265F qnvalnr]Ц9% @   ??9/9310!#67'3T-)8QT˝֊:2q#9,@  sYuY?+9?3+39310)7>54&#"'632!w!~;teOXVKQ`q=B{jʼ-3(>@!# & sYsY $& sY ?3+3?39/_^]+9+310#"'532654&+732654&#"'6323ȳ~ԭU^nc^MT zrO/7XjA6 J +@uY _??39/]33+310##!733!6#'HHv9nJV^LL6^.$LJ3@sYuY sY ?3+?+9/+39102#"'532654&#"'!!6XՓȆԑ.UgL#{aұyOf| ;X^((@!sY sY sY?+?+9/9+104$32&#"3>32#"&2>54#"{oM%JbC;j咹[P@x^.w"M]ŬRjn7aq]@ uY??+9103!7!9!\X&29@--sY-- sY 'sY?+?+9/+_^]99102#"&5467.54>32>54&">54&ŞzmxܺZTp oZHf nJXoͮMJtzfĪM@dr_7wh{CyJcjM}68dXf`-'(@!sY sY sY?+?+9/9+10 #"'532##"&54632%"32>54&-ojj@ 3d铴yjiZXrWݎ"-%HWƽLݬyWy)f @ }Y }Y ?+?+1074632#"&4632#"&)UI-7RF37TI-8QG37NL^76H`8N^48H`7f@ }Y /?/]?+10%#734632#"&3btV`TI-8QG37N^48H`7w$@ @p/_/]q10%5 ef}7@&~Y~Y @`p//]qq+9/+105!5!}d1w$@ @p/_/]q10 5weDnfX&7@ p $$}Y$ ]Y?3+?+9/_^]]9910>7>54&#"'>324632#"&jpxR.c^NDAZ[PSJ-8RF37XZYa>Yc4 07z{^kdL^76H`8mF7B-@8>  8  ,4&0,%??99//32910#"'##"&54>3232>54$#"!267#"$5$!2"327&p{isCX`!bI|P _dˤ F\ZVD9Rޤ$r>qz.(Z9 bnr7@ mY ?3?39/+10!#3# &5/I! L9Jj2uM^T!:@ !!iYImYmY?+?+9/_^]++9102)32654&+!2654&+۫ry-53| n{ahqx @mY mY ?+3?+310"327#"$32&fΖI)ջ<=+RHT @ mYmY?+?+10)! 2$54&+y5Z *ooITo 7@  mY-@ImY mY?+?+9/+_^]+10)!!!!!95#a q18To @ mYmY?+?9/+10!#!!!! 5!m "P(@mY mY mY?+?3+9/+10!# $32.#"327!/՜yjiuhFMiǴo^5*!# (."2ݽ%Vy (mY@Im ?3?39/_]++10!#!#3!3D}5Vj  @ lY  lY?+3?+310)?'7!d)'ff'd){B mY"?+?10"'73273i2EL43R{H}T5 @  ?3?39910!##373{51}:?}T\mY?+?1033!T51#R@    ?33?399310 !#7####!и=&?35 JdVR@  ??910!###33>73}<55 ,H]>% @ mY mY?+?+10# $32%"32654&P􆾤U* ͑hT @ iYmY??+9/+10!##!232654&+Ńy5Jۈ9޴zl @mYmY?+?+910## $32%"32654&P􆾤뉷OJ* ͑׿dT(@ mY mY  ?3?+9/+91032654&+ #! #ʂ5BukEg{\''$,@"  mYmY?3+?3+999910!"'532654&'.54>32.#"̈crz߈ǨF@INf4AVLtRYr}jV$,sNfLWez@ mY?+3?10!#!7!!n# n@  mY?+?310#"&547332678 + d6) \'i-<Vh o\T]tJ @  ?3?39910!## 33%Sy/H@ ??393310 3#3!pwi% $@mYmY?+9?+910)7!7!!ysz#aq$?3?310!!#3yu|!-Z ??10#٤Jms$?3?3103#7!!u; wӓT''?9/99103#TVq 3'f!DH Y/+10!7!q-9!@ /]q10#.'53nB)fB7bf^ '@  ]Y]Y?+?+99??10"&54632373#7#'2654&#"]* A^rlYebZIJcb\ߕ!byon9=#&@ ]Y]Y?+???+9910"&'##33>32"32654'_& CJN2fY_okfbbbZY|cò۽hu#b^@ ]Y ]Y?+3?3+10"&54$32&#"3267֓}3shndrI?P54}(Ab!'@  ]Y]Y?+?+99??10"&546323673#7#'2654&#"V K`!]phecc´dżcfwhlrb^ "*@]Y ]Y ]Y ?+3?+9/+10"32654&"&54632!#3267}g)Hغԓ"y~MQcto5D#¼VÇyL~,(.!*@ _Y ]Y]Y?+?3+?3+310"'53267#?>32&#"3#bF=>4FV.a_/J?XX(py.KDbʣ'duh3h^ *0@&%""]Y"]Y ]Y ?3+?+?+99?10%2654#""'5326?##"&54632373ZseabŅ?K 3[]W C/!ީޞF&0EujIJew9/@ ]Y  ?3??+910!#654#"#33>32W| dJX $ YeY.wݚ'm>Auj8p9)@  bY??+103#34632#"&괅C6^F/+7J9J\ q{ рCHNwiRw d Dcu^sX\d^1>JsՏ^)vߙ'JZR39/^@ ]Y  ?3?9?+10!#654&#"#33>32FLV~ d Ck}Fc*?Kvߙ'JVV3Nfb!X @ ]Y ]Y?+?+104&#"3267#"&54632hxgj\{rd[ڔsP=\!%@ ]Y]Y?+?+??99102#"'##33>"32654Y  dP_]skfbb\ȯü1&6vihu#bf^"%@ ]Y]Y?+?+?99?10"&54632373#67#'2654&#"]( Cc#[!Zvi`agIJfb\i{uj gwݤ9o^@   `Y?+??9102&#"#33>F1'81Zuj I^h^ u} J`R- L^$,@" ]Y ]Y?3+?3+999910#"'532654&'.54632.#"˴AMz~Esk̩:5YXiIlqU-=E(0_M7OAH^L+SC7MSi'}j72xw@RTQNQ)0AqfJ@]Y ?2??+910332>73#7##"&547W d ZcJNZ0vvi@pbJ  ?3?310%673#3qq9C= i\J\'uJ@  ?333?3?310#33>33673#'53P-  OD#4i{JPEÕ6;-RJ @  ?3?3991033##B85jV?J!@ ]Y ?2?+?3931033>73#"'5326?bG h?GZO??ERv6GJK^B9ZgbJ @_Y_Y?+3?+310)7!7!!))c {H3&@   $ ?3?39/33104#7267>;"3# 54?6"vD!%f]Gi-HR1oWhAGWy{(9HA402YK ??/103#&0@ ?O_/_$%?2?39/]q3310 3"+5267>75&54?654-1!wC#qfG~k/R`2YUVhHV?wy*9H8&41sL1X+@ ~Y  @~Y/+3_^]2+10"56323267#"&'.\62cFxQMV.73dF{MMUE4l"!B7n !!^)@  }Y 0/]?+9/_^]]103##"&54632w QE37TG/6eF`64L^8+A@sY  sY _o @ H   ??99//+]3+99+310#7.546?3&#"327F+!%\3qjngrr{"͜> &3}E>?@# tY ?uYsY?2+?+99/_^]3+3102&#"!!!!76?#73>LFj}Dm-ZQ#C5-H%VNts‡f*.чV'%%/]321047'76327'#"''7&732654&#"D`gppebDD``utc^DegfdqdbDD`lktc`BD``uceg{A@%tY tY ?O  ??39/]939/3+3+310 33!!!#!7!7!733H!%:8!ʰ@ ??99///3103#3#7+72@12##_Y(*7,  _Y ?3+?39+91047&54632&#"#"'532654&'.>54&uұ7uavLxqwnq͵v8KQvuVNhaM[hiIF>OC1F5<[`7Ju? 0XR,J8:SxGC]@*zD>]  0@  0!HH/]++q32/104632#"&%4632#"&:2R9-'1p<1*(=,%1b3BR1H,*4A-%4E,h%5M@4 o     `p  *"20??99//]q]q3310"327#"&54632&4$32#"$732$54$#"z]xAb:~~>l^Zm+)׭֭->}6^ZƬ֭)(*@ 0 [ 0[?+?+9910"&54>32373#7#'2>54&#"\PdT`r'%\`3e54&#"'632!V;9_d?lhJp⃀B3>P`gs^azu9#Q@4'+ _ !+0 !?3q_qrr?qr39/_]qrq910#"'532654+732654&#"'632GLl}rhc^_^sC9f^9ru7dE8HYMqNG;:DcXq! @    /]q10>73#3-/Iq7E95sJ@ ]Y ??+??391032>73#7##"'##33T~#i ^^q1)BPuۜze^6NX'@0@0/3?39//]10####"&563!ww>T1y3G\}dR+@ r i    0?/9/]]]9/10#"'53254&'73ס7% *=Mcr;cw jm%/ u&J ??9/93103#7'l:Xk9LE` @ [ ?3?+310#"&54>32'"32654%QftTdwatIB]p|owoTR\o{ @   /]]29/10 '7%'7{wX'}la}XE6A kLfb6j~^'j&{;w ?55K'7&{t?5]10[&u'; +?55qX&H@,  $$}Y$ ]YO_O0/]]q3+?+9/_^]]99103267#"&5467>7#"&54632gs1ZD)c^=`Bú|RUI-7TC29Z'HO\:Xc'-f{v[kiNO]66K]5s&$CR&+5as&$vR&+5Fs&$KFR&+53&$RdR&+58)&$jFR #&+55$6@0"@mYO " " ?3?3339/]r+10#!#&54632&54&#"326A77X}`d{2 L@30@:63@/Jd9y6~atr͆7M^5<<55<<D@ mYmY mY - @I  mY?+??99//+_^]+++310)!#!!!!!#`J c o/wTT98V&&z%Tos&(CR &+5Tos&(v}R&+5Tos&(KDR&+5To)&(j?R  &+55 s&,CR &+5xs&,vR&+5Us&,KUR&+5K)&,jYR  &+55D K@1mYo  mY mY?+?+9/_^]q3+310)#73! 2$54&+!!y"Z *kB#fooI R3&1RR&+5s&2CjR&+5s&2vR%&+5s&2KR"&+53&2RR%&+5)&2jR 0&+55-{ z@  x  @BH    wH/_/]q2232]]]+q332]]]+q332310 7   'h>Ag@ef?i@gf@gu( @"%mY%mY?+?+9910#"''7&5$327"&4'326ÇtiPվw02'\/\U^^k^?5XTdmTFfs&8CVR&+5s&8v!R &+5s&8KR&+5)&8jR +&+55s&<vXR&+5TV #@ mY mY0   ??99//q++10!##33232654&+VD55ڊ;೩{kh=9@27]Y2(  (+]Y+]Y?+?3+9333?+102#"'532654&'.54>7>54&#"#"'53267>Tr>l\gjݻ_+Fs8NWH&@\M?"hXw(G64;@U+OW.PB7AI[G#7q^=X>Co=6WHB4>C&@I}]lbf!&DC"&+5bf!&DvH*&+5bf!&DK'&+5bf&DR*&+5bf&Dj 5&+55bf&DP $&+55bb^*8BK@,32!#3267%2654&#""32654&l*xh^{P Cs7hz){;lo\sZLbaIq/DMN~aůfɾLVxL~$0K&evpoHsl9Db^&Fz}b!&HC$&+5b!&Hv5,&+5b!&HK)&+5b&Hj 7&+559!&Ci&+59!&v2 &+59!&K &+59&j &+55Xs .(@@(]Y!]Y??+9/9+10&'7%#"&54632754&''2>54&#"?Qa|DBVN҆g$EJ<8gd}ojTq596{SEmq|;XN[nmrps|z~9X&QR!$&+5b!!&RC&+5b!!&Rv;%&+5b!!&RK"&+5b=&RR%&+5b!&Rj 0&+55}p@"%H@"HIII@#I ~Y /_/]q+3/_^]+++++3/]+105!432#"&432#"&}q5=>40Aq5=>40A{=>=>9{=>=>9;R' @%]Y]Y?+?+9910#"''7&546327%"&2654'ebmoFfdms>li`9d^ 5?}ThPA|QacW&s-H%+qf!&XC&+5qf!&Xvj"&+5qf!&XK &+5qf&Xj -&+55?!&\v"&+5=%'@  ]Y]Y?+?+99??102#"&'##733>"32654]+ d$N(#d Zvjgbb\Ʊ`\iQ&Tvzejs#?&\j -&+55?&$MfR&+5bfj&DM#$&+5Z>&$N7R&+5bf&DN#&+5D&$Q-bDf^&DQs&&v3R!&+5b!&FvB"&+5s&&KR&+5b!&FK&+55&&OR &+5b&FO!&+5s&&LR#&+5b!&FL$&+5Ts&'L^R&+5b&G8Db5*H@+]Y _Y    %]Y ?]+?9/_^]3+3?99?+1023767!7!733##7##"&5462654&#"w]* !s$'d\\skdda^_[W5+zeIJa#msٝTo&(MZR&+5bj&HM&&+5To>&(N;R&+5b&HN%&+5To&(OX5&+5b&HO+&+5TDo&(QFbc^&HQ #<## >+5Tss&(L/R&+5b !&HL.&+5Ps&*KR%&+53h!&JK1&+5P>&*NR!&+53h&JN-&+5P5&*OR'&+53h&JO3&+5;P&*9+3h!&J:u/&+5Vys&+KR&+59?&KK?"&+5T4@ iY mY  ?3?39/+9/33+33103##!##7373!737!HṐ}5560}0V-9+C@' _Y]Y  ?3??]+9/_^]3+3910!#654#"##7373!!3632T ^ ')ZX ˂V/v7Շᐍ:n3&,RvR&+59(&R &+5M&,MtR&+59j&M&+5j>&,NGR&+59&N&+5D &,QD)&LQ/ 5&,OR&+59J ??103#3J{&,-97&LM{*s&-K*R&+5!&7K&+5T;5&.97;3&N9J73J@  ?3?399103 ##33^)%Q=!J)usJKFoTds&/vR&+57G&Ov &+5T;\&/9F;7&O9T0&/8 ?57&O8LT&/Ohe >+57&OO| >+5\ ,@  mY?+?99333333103'737!Rlj@ͦ?`/#>wugs5X ;@#    yFV ??99]]]33333]3107#'73w9՗}p>ѬmEp=HDq Rs&1v1R&+59/!&Qv\$&+5R;&199;/^&Q9XRs&1LR&+59C!&QL&&+5U'QR}"@ mY"?2+???39910"'73267##33>3j2EOf- $5,&}tmWV7J9/^#$@ ]Y]Y?+???+910"'5327654&#"#33>32B=>8|*FLV~ d Ck}F%;c*?Kvߙ'JVV3DpĮ&2MR&+5b!j&RM&+5>&2NR&+5b!&RN&+5s&2S)R /&+55b!&RS /&+551!K@ mY-@I  mY  mY mYmY?+?+?+?+9/+_^]+10)# $32!!!!!27&#"VRNPՖU!b !n1G6No* 8tb^ -7F@&1]Y11.]Y  !]Y (]Y]Y?+3?+?+99?+9/+10 '#"&5463 >32!#3267"324&%"32654&Zؓ[Jy+z~8qi^yjty+@NjwyL~8Kג;zyp0CTs&5vR&+59!&Uv&+5T;&59;o^&U9Ts&5L5R &+59!&ULz&+5'0s&6vmR.&+5 !&Vv.&+5''s&6KR+&+5 a!&VKa+&+5''&6zH L^&Vz''s&6LR0&+5 !&VLM0&+5;&79K;D&W9s&7LR&+5Z}&W8;#&+5(@iY  mY ?+3?9/3+310!!#!7!!7!! ߍ!in# n3bᢢ)D"4@_Y  _Y@]Y?+?39/3+3+310%27#"&5467#737#?3!!3#>Si' 25j75 2xw PQN#0A3&8RR &+5qh&XR1"&+5&8MR&+5qfj&XM/&+5>&8NR&+5qf&XN&+5&8PR H&++55qf&XP &+55s&8SR *&+55q!&XSF ,&+55D&8QNqDfJ&XQs&:KoR$&+5u!&ZK$&+5s&<KR&+5?!&\Kv&+5)&<jR &+55s&=v\R&+5!&]v&+55&=ONR&+5&]O&+5s&=L!R&+5!&]Lz&+5m@ ]Y ]Y?+?+10"'5327>32&#"E:<5-)5k#0J=YZ(«etͽ\ /@ _Y ]Y]Y?+?3+9/3+310"'53267#?>32&#"3#G:<7>]ɽ %'j//J=YZ(svID«du;u%,-N@.)mY))# &&#@ H@H@0p#@H##-?3?9/+q++3999/+10#!#&54632%673#4&#"326! Z5+zcf{[2??30A;63?,2!tA9 4X^ysQ2&6<<65<<\dx!'bf 3A[@60-2,!(/@0@ 0@H@ H((;]Y(!4]Y!?+?+++_^]^]99??10673##"&546324&#"326"&54632373#7#'2654&#"gz4E|zcfy~ab{lA03>892?E]* A^rlYebZ_4(ctsbavre6;;63>AIJcb\ߕ!byons&vXR&+5bb!&vL&+5us&vR2&+5;R!&v;1&+5';'&69 ;L^&V9! @  /]q99/10#&'#5673q8iqw1"`*0qIQ\BD!@    /]q29/103673#&/l@b~xuB:"[+!2pK=Z_Bj@ 0/]q10!!'j# >@%0 @0 /@ w  0/]q]]]q2/10!"&=73327#?skIZ!zk*5lF#+#:9#*#3?{! @    /]q3210>73#%>73#1$-F^Z/,1G^5<923F?2hs @ @ H  /9/+10>73#h)mFqML9TF ?@?  0!HH/]++q3339/]q10673#4632#"&%4632#"&g23EQ=.R=*%1=.Q;+%1{G? 4AR4E,*4AR2G, &$T ?55G\}dB &(yT ?55BH '+T ?55Y ',T ?55W &2PT &?55B '<T ?55T &vhT +?55h&U .&+555$T%TomY?+?10!#!! 5!(To(=Vy+M@1mY&"I"!I I'I: 6 ImYmY?+?+9/+_^]_]+++++10!7%# $32%"32654&! uQ򈾤7TY+̒ؿf ,T5. ?2?310#3#&'u·lJ`LmR0R1o 7@ mY-@I mY mY ?+?+9/+_^]+10!!!!!7!}M0#f#!L 2T{@ mY?+?310!#!#!F}5T3 $@mY mY?+9?+910#7 7!! !b#i#^17<!3@!iY!mY !!! ??99//]3+33+3107.54$?3>54&'#)17$%1R ʼ؝| ֊ؓ;P#@mY ??339/33+310###"&5473;332673j$_^TZ*fi5B[rTjF}\  %@mY  mY ?3+393?+10"!7!&4$3 !!7654&b~ap ^ȷGk!+ڸpFrxK)&,jYR  &+55)&<jR &+55bs&~T9&+5=s&T1&+59/s&T$&+5hs&T&+5P&U 0&+555b^!/-@)]Y ]Y"]Y??+3+?+9910673327#"5##"&546322654&#"40[ H"#M]WT:^piZe`Zu3;82#' pZǯbȼ߳bypo*1@#$$#]Y$$ ]Y ]Y?+?+9/+9?102#"&'#>"3265!#732654&IJ{WN}R&~xs&3GB!Hm&2<4f(.bqRJ  ?/3?310#633673*K D\7>JCLHs+Z@6## & &9&&&&  9   ]Y ]Y?3+?+9_^]_]9]39]9310.54632.#"#".542654&'N`PʦH^54&'.b1`!Rxmb/fTDv{2Q vgs5.IZ=Ww:,>0BY9/^@ ]Y ????+910#654&#"#33>32FLV~ d Ck}Fc*?Kvߙ'JVV3Nfb7 D@*]Y I"HI ]Y ]Y?+?+9/_^]++_]++10"&53 '2!"!65K몁MYlHmG B|hJ@ ]Y?+3?10%27#"&54736W!i&}zu/g H0s73J!'@]Y ]Y ?+?+??9/310'.#"'632327#"&'&5# I@<*DIu =!"3A]X )<; 3m[ l flkHsJwbJ  ?2?310363#b+2IMJKxHRb239@11_Y11(5*'(']Y( 33]Y/?+9?+39/+910#"#>54.'.54675&5467+7!#"!39Mz[~_a6K_rF F[~׵1EY:!m'^Wl[j3$H`32%"32654&3XC &G3ou+P/Dh^o;CCqH49bV^ ,@]Y  ]Y /?+9?3+9310#>54&'.54$32&#"^bQ[]]Fh3snkkIw37yXHRT?2<(@ИH54SbJ@ ]Y ]Y?+?+310#"&54$3!!%"3254'ђ6(vuFXٖ,` {NJ@  ]Y]Y?+?+310%27#"&547!?!!:Wn#s!t2xw9JPn30APJ@  ]Y?+?310"&5473 323pHHra̴GGtkb \#$@  ]Y ]Y???+?3+310.547>32>54#"sdřs~)blHMEkw +m ptZN/@ ]Y]Y?+??+9933?1023327#"&'#.#"'6eo'D 8:$.H?kt-?b< 3.0 >NsNYG k|FO>w @  ]Y ?3+3??3?10%>3#.54733beflmux-Yr. $ǫPhN{ bJ'$@%  ]Y"?2+3?39/910"&547332332654'3#"&'}:A>A!3 4&+ivrL343Qh^i|L3`W 7qjT)@ mY  mY?+??39/3+310)!#3!33 3 4&+Ӑ5-lGh{ThN7qh#@ mY   mY ?+3?39/+104&#!#!7!!!2#6ej#"lV \\9WO!m%hGTT7s&vR&+5Tf&6jR&+5T{ @  " mY ?3+??3103!3!#!^PT\J$Vo &@ mY  mYmY?+?+9/+10 )!! 4&+P5#`$k|sL8P7qjT%ToaT $@ "mY mY ?+33?+?310'3!3#!# !9hlITuPR(\/ JSlTo(-@  y ?33?339]3333310 333 ###?`ufqHH#'''3'I@*iY "II  "%%iY% iY ?3+?+39/_^]++_q+910#"'532654!#732654&#"'>323DzWg»zgJkᅯ$pO15򕢎eawHDT@    ?3?39910 3#67##35ˬ4^5>J=mTf&6R&+5T7 @ ?3?39910!##33-F5-+:%;@mY mY?+?+?10 #"'532>!#얓vrL343Qh^ɸ3`W JR0Vy+2T{nT3&7T @  mY?+?393910"&'532673673(cPVe`͸3D5^ 'uVZ֫s;R^ @ " mY?+3??310%#!3!3wR/5f-@ mY ??39/+10!#"&54733273?;mjRb۔TXH\X+MNPJR @ mY?+3?331033!3!3R5JR@ " mY?+33??3310%#!3!3!3NuP5 &@mY mY  mY?+?+9/+103 )!7!3 4&+T#j|L7qjT` "@ mY  mY?+??39/+10!#3)33 3 4&++55/j|+P7olT @mY mY?+?9/+10)33 3 4&+5-k|P7ols9@ mYI mY mY?+3?+39/_^]++10%2!7!74&#"'632#"'5y.!\aG/ƽÚvX'JJO8'T#3@mY mY  mY?+??9/+?+9910#"47!#3!!2%"32654&5:Co瀭߃R, CDV&[ΐּi (@mYmY ?3?+9/+910 #&54$)##";X5͹^gJ^xbf^Dd(=@!     "]Y ]Y ]Y?+?+9/9+9_^]3104>$7>32#"&2>54&#"d0VqiiL`꛼[WUWXHvES9+TsZ^îŝVz|qxcQb\)z@R##]Y#/I#.I##)%I## I##2I#.I#)I#"I## I#7 I#2 I##]Y ]Y?+?+9/+++_^]++++_]+q+q+++9102#"&54$32654&#"32654&Žm`jȍݐჃ{&ߧa\osZaW;1iWOM촦g_GM3q\$*@]Y ""]Y?3+?399+9910>32327#"&54>7>54#"xLa/`gOa0,"|lE>3227.#"=籬Uoh-2G/#~TZ]f/Ӽ@ -$*qvwb^H^<r@H:_Y"%I,I'I#IO I 4 I/ I<(]Y#/  ]Y4?3+3?3+3??9/++_^]+_]+++q+3+310##"'732654&#"5632333>32&#"327#"&547## 5G4/3cge`5>W7df!{P=!+?ccd]8:S8f'"%s 8V^'Y@6&''&]Y' +I''' I'"I'I ''' ]Y ]Y ?+3?3+9/_^]+++]_q++910 54&#"'>32#"&'532654&+7TVHP5[d}T=JRdk#=H##+){o1$!+-q\VLqfJXqy&X63&+59DJ @  ?3?399103 ##3bnrqJ#JT+@ ]Y `Y ??+?+993310!#&#"#"'532>7>323%)L^OU[nc2");XQE0Tpxv;W FˉʅA#9\J@   ??3?399310#&'#3673#fjn"Yj'jHJA8M9J .@]Y]"I I   ?3?39/+]+_q+10!3#!#^bfhJ7Jb!XR9/^Q=\Sb^F9^P?J\b#+@ #]Y ]Y ?3+3?3+3??10#.54$73>54&'{ʟ߷ddǚ^B}n~cdzrZźˮ$˸, @3猊 J[qfJ"%@ "]Y_Y??+?+?391032>73327#.5##"&547͔W d&(3sR>9؂JNZ0vF3#+ocaۏ@p=J@ ]Y  ??39/+910326?3#>7##"&54?''FO/.1&Dj6J-IIsoZb6qJ*%@* %%]Y ??3+3?33991032>73#7##"&'##"&547332>7JSv d Z\q{ ҀCHNwkJP^*wݚzerDpPh(>IrՐqJ6.@"$6 *1$1]Y$_Y/?+?3+3?33991032>733267#.'##"&'##"&547332>7J=HSv d)#(uP>;q{ ҀCHNukJNZ,EJwݚU$&( ocaہr?uNd*>IuԎTLJ&@]Y ]Y ]Y ?+?+9/+10632#"&547!732654&#"fXfĆb!tqhiTuJ#o^MsɚtaXFsJ"@]Y ]Y ?+?3?9/+10632#"&547"32654&#3gWǮVpmi:J#ˢYgcj^ZqdQMH\]@<]Y +I"!I"I 9 I5 I ]Y ]Y?+3?3+9/++_^]]+]]+q++102#"&'53267!7!54&#"'>эE*s)|ws}5>\;:*9X"I@+]Y ]Y"I I  ]Y?+??9/+_^]+]+?+9910#"&57##336$32%"32654&헷h^AweVrk]ToVJ7L~ tJ$.@""]Y""]Y ]Y?+?+?9/+910"#"'5326767.5463!#";?7M<):N`C2"4F.Hs_`]nvѴL!FUx\, F`*]g[fb&Hj 7&+559'*+S@0$ ]Y    -+&'&_Y''''$)$]Y?+??9/_^]3+3?9/_^]+910!!3632#"'5327654#"##7373Z % ݁%G84B|*V~ \'\Nݏ>jﰞnvߙPՇ43!&v .&+5b^]@<]Y +I"!I"I 9 I5 I ]Y ]Y?+3?3+9/++_^]]+]]+q++10"&54$32&#"!!3267֗}3sh{/#6p9s\[54 @|*A L^V9)L9&j &+55'MT)5I@*!$!']Y*]Y '`Y 0]Y ?+?+?9/_^]++993310632#"&547&#"#"'532>7>32"32654&}UfĆ` :LJSKtd4",;XQE,MgpwrLYpqhmo^Rn=^ FˀȉH%n8taXF9 J"I@+]Y]Y"I I]Y?+??9/+_^]+]+39/+10632#"&547!#3!3"32654&݀[ŮJf`bCVuqhmɢ\iJ7r6rcXF9+9D!&vD&+5?&\6&+5qfJ.@  ]Y@ H??9/+?+?39103#32>73#7##"&547)]RHW d ZcFZuNZ0vvi@pT@ mY?+?103!#@d5+19@ _Y?+?10!#!3NjʵF=J=s&:CR&+5u!&ZC#&+5s&:vR'&+5u!&Zv'&+5)&:joR 2&+55u&Zj 2&+55s&<CR &+5?!&\C&+55y@ `Y/_/]+107!5%9"Ӧ5jy@ `Y/_/]+107!5%"Ӧ5jy1OڲI޲III@ H/ ?]29/+_]++++310!7!!7!-R-cn{ ?10'63Y={@ o/?]q10#7 (XE[*3/?/]10%#7+btV ?10#&'7>{  ?3210'63!'63P8Y=*{ ?3210#7!#67 (XE=W4[*tD= @  /?/]3210%#7!#7+btV<Z?< @ 0 ??9/3210%#73%Ǥ%%%ՐF! ] B1@  0    ??99//]323210%%#773%% F'ׅ&8g'7ׅE' y$! z !  /3104632#"&tonuwlnuzzz)F&'C@8 >?OO__@]]qr5+5 *9FUI@,A%0:7S7`7777o77L00????399//]]32210"32654#"&54632%#"32654#"&54632%"32654#"&54632Af?g>fC?fWp{grvz >@d?d?dE=fYq{fsv{@f?06?dB=gVq}hrvzF{ugla2|JFzt}fld- |xRRglb2 LVo7@  /]]10VX٨}BX5o@  /]]10 '7yY'}{XM{6I)' ??10 #¢>J!@   [ ??3+3910654#"#3632;VLL=khGWNA)T~QQ:Z)<@!tYuYo uY ??+99//_^]+3+310!!##73!!!!97#n#)$U@0 tY#$#tY $$$$ $$ uY sY?3+?+99/39/_^]3+3+3107!2.#"!!!!!!7>7#737#7h2Me[FF4C/-l#m[M#Cl{!ye-) .Ӊw*7$-?@"%"]Y _Y@%%$-]Y]Y?+?+?99//3+3+10%27#"&547#?33#32!##32654&+32&#"3267 ##"&54>32%"32>54x`uO['KDi0I]GuThvWk};V/ul"i! kJzyn"TMo$/@ #Yi 0??9/9]]10%273#"&=56746324#"6}iPpNrxεP{A>wөy&ꐟNgx!UgV7Z *E@&"kY (kY iY  ?3?993?+9/_^]+9/+10!##3737!#"&54>324#"32646Z;h!ZeyWet}Un=>XmǴN\1%Jrfvn|KSw,@ 0?233339/333310##5!###33#7#}@zell%4ET)/yv}H/@ /?0?22?9939/]10"&54>32!3267.#"1RPGbٓ2Xz#5Fi)|5Bu^'J&{> ?555UJ&u'>D 4?555]R'&<>L ,?555Z'F'>= ?555sJ(*@ "]Y ]Y]Y?+?+39/9+10#"&5463275!"5>322>7.#"J겮阻\>87A_vNi`a;6("("&ҍTpzuw @  mY?2?+93103!7!&:cpNmoP@ mY?+?310!#!^^T $@mY mY?+9?+9105 5!! !qC;q+r} @~Y /_/]q+105!}b?3/9/310##5!3' gP".S@5#0`p`p@)0@@//]]]q]q99//9910#"'#"&54632>32267.#""32654&P~|=VW>:\yAk52jGJ`^Ak83nEHb_̓fqmpdqYa^\kQSenYa^]jSNj#!@sY sY?+?+9/10"#"'532654632&R1I*Z^U.7ups{1#/q@G*$~Y** * *@'~YP`@ ~Y  @~Y/_/]+3_^]2+_^]q+3_^]2+10"56323267#"&'."56323267#"&'.\62cFxQMV.8~5dF{MMU146bFxQD_.73dF{MD]E4l"!B7n !!A7m"B7n !}@O~YO_o@.1H@+H@H  ~Y p  @ `    $)H @ H /  /]++]qr_q33+39/+++_^]_qr3+3310'7#5!!5!3!!g={Hj}7ߔ;} @:+[kH $Td@&H     ~Y/+/3_^]q3]q3+]q]q3]3+]q]q3]1035!55 }d䓓g} @    $ T d    @FH +[kH~Y/+/3_^]q3]q3+]q]q3]3+]q]q3]1035! 5}ddDlgYf  ?3?310 # 3 f73#`;d.:5:; /10>73#%R=bV=G3:1! /10#5>731!]=d4;9=XJ ;@% 0 /?_  ??39/]q3_q29_]10##7!733!7ρ))y}GPkAH;4]9-@  0 !?3q?9/]q2102#"'532654&#"'!!6qVqw\tign[GG>7{?/mq_R4FhWBI/ J3@ 0 ??q910!7!w%-Jyb9".I@1)))')7)W) )))) !###?q?q9/]]]qq3q99102#"&547.54632654&">54&o~m^I?u=/+^VO?HUEDI)7XF?rWRx /dBuufT.U=g#Y<9@PA2VF5(B#O6.6T #'+/37;?CGS[kt|)@cddz0<@1=A TN HX#4,lvvk7/`pgz8; $(D%)E zp/k,XN cuu{llZljlllk\}}VKKvkZQDkTkdkk k0ktQk0\@\p\\\/\O\\\ B*A)>F=E2&1%  -, 48!59/33/33399/]]q3_]]/3/33/33/39/_qq3993333333333333333333333310!#%5!#533!5353!5!!5!5!#3#35!#35!35!#35#3#3#"&546323254#"%32+32654&+32654#"'53253T/0momImmmm0oowoooomm~smp.,=.m^{B.$*/;J1%Z^4+V}i0oo/mmmmmmoo;mmJoooo/yhIaCS1BD5QYb" "+%J fVr_cT*,@ % +,((""//99//339910 5467>54&#"63232654&#"TV,AgIOGRZ?>1HT;GFBIHCHEVW/2A1R~X8*P:/5K6DpJ;?HI>@IH!&7L&+5{5 <D@'_Y //_Y:@ 55]Y5+]Y?+?+99//_^]3+3+10365#" #"&5467>54&#"76323267,546323%S_#(.5 UGNV!RMk$ȠwtJTp+kŒH?&J""YH;n56g8ILJ@$!@ iY?+??933106>32.#"#3!T}fC-A&,U}jnw٠{9Q%jJ+1@!!   ]Y (]Y?2+3?+339/910"&547!?!##"'4'!3273326Ëpig!{Ԋ/kDI>=%A891?buqdavw`5<<55<<f,(@ ^Y ]Y(]Y?+?+9/9+10.#"3>32#"&54!&#"32>5i%$#[7? :j瓸ɶWTpa2aQ;vk]L M]Ŭ۟'|+BJ.|.jD;?JN@*CHbYC@>=* 88_Y' #]Y 3]Y.?2+3?333+3?33+33??+10"'53267#?>32&#"!7>32&#"3##"'53267!#34632#"&bF=>4GW.a_/J?XX-d_2J=XY(K6:9EV'(뵅C5]F/(8vs.KDbʣ'duhjǤ'fshwr.J9J\:M2R;?E@$>=* 88_Y' #]Y 3]Y.?2+3?333+3?33+33??10"'53267#?>32&#"!7>32&#"3##"'53267!#3bF=>4GW.a_/J?XX-d_2J=XY(K6:9EV'(Jvs.KDbʣ'duhjǤ'fshwr.%,@ mY@ H mY?+?++99310# $32>73"32654&PՕBNU"+􆾤U* pi|;vhbT$&@  !]Y]Y?+?+993102>73#"&5464&#"326nN[!!ڔ{xgj\{rd[X!6RhPms@  mY ?+?39/31063#"&54733267+) #㭉8-"}Rmrk=q!)@!  !]Y??+?39/391032>73>73#7##"&547͔W dQj"寴 ZcJNZ,v}!vi:p(x!C!vRc) @H 0/9/]+9/10#7>54&#"5632papZ^=3!@,KpzS_k30(hV{}  H /+3104632#"&E40,E0(89J4(;L0Tos&(CR &+5Ts&CjR&+5b!&HCY$&+5qf!&XC&+5m91@(,,!!mY3((mY?3+3?3+39/910"'632 #"&'#"54$32.#"326?332654&6^4Jrt"7p״kV2Y6y~zl5-[U՗k'+X߷kВ\TWYZ (eƬU7SWјhJ @ ?2?339]3?310333673##섵E ;5,-oo4K۶3J{Sh\ht5V}3@mY  mY mY?+?9/+9/3+310)!7!73!!3232654&+}!/36m!4/sڋ5 obZ'$-@]Y]Y @ ]Y ?+?39/++310!632#"&547#7373!"32654&Hjα`/-j|ehwi̞dZǚn8^ZqdTJTF%J@#!!mY!mY@I  mY?+3??9/_^]+3+3?+310"!!327#"47!#3!6$32&Ag! ^_ɐ564.͚L):U<"&GJV!RH9^%j@C]Y  +I"!I"I 9 I5 I]Y $ ]Y?+3???3+9/++_^]]+]]+q+3+310"&547##336$32&#"!!3267h^:Ð4sh{/#7rNz<~25J7543y(A{ !@ mY ?33?39/+310!###3##7'&'^uwVkpX0VLVkJ #@_Y   ?33?9/9+310#####&'MYdoX@xJJ/|Tf-@   mY  ?333?9/3+333310!####!#3!3!'.'jqwy5i HVVVhLL^\UG9VJ,@ ]Y   ?333??9/9+3310######3!3# XVflV!h`7 ⼲`0J7}H 3@   mYlY ?22?9/3+3+93910#>77!#.+##" !RJti%+ez= Uc i{EşL鋋N9ɋhDg=^J5@ ]Y^Y ?22?9/3+3+93910#>77!#.##" !o8c[rq0.S\on\r6!+jkf< `iiRiQ Mk)T'D@$"lY mY mY ! ?333??+939/93/++310 !>7!#3!7!#.+##""B+5%,ex< VahzD^Gt*Vߋ N9ɇlDc99PJ"D@$ " " "]Y ^Y ]Y  ?333??9/+3+3+93910!67!#3!7!#.##" !;-5h`rq2-SZqj[l;-jW+J7`iiRlN Ln)V3K@(>>%>>7;;FAA/A A7+*+*iY++++@#I+I +++ I5772iY7mY# #mY ?+?+?+339/_^]++_qq+9_^]29/9]10327632&#"#"&54>7>54!#732654&#"'67.'53>32&#"3DzΩi9mmGBX&cnSgXZ»zgJ/T|OG_m8-%%AOt$37T %wf]xGFza򕠐eawt!M{V_tIs4hwRK@ :/]Y:!KJKJ]YK˲+IK@!*IKK IK"IKI KKK ))B_Y)@ H @ H  ]Y ?+33+29/9+?+9/_^]+++]+++9/+10 54#"'67&'53>32&#"32632&#"&54>7>54+7x6z*c}JGDHI+/'%%H9[c}YbgpR)tXL1X-][|CoK=v]:ϖ!F>LT^WB#u;N{]owVjX+L 'l`N`: 0L>Puw L@1mY)"I$!I I I I7 I mY mY?+?+9/+++_^]++++10# $3227!"!654&P35X5IU* 8;2&b!X W@9]Y +I"!I"I 9 I5 I ]Y ]Y?+?+9/++_^]]+]]+q++10#"&54632267!"!74&!ܔs&{v(+rP>@F}m@  iY?+?3?102&#"#3767>>;25&32&#"#3qNGLn4%+A'y=˘Mo AWJ[gms&}s%R *&+55`-!&~s{ (&+55 &2\bX&R\1.2@-@mY%(@#((mY ?3+3?3+310#"&'&54$7>32%"&'6326'J6;>ʣ)I9;>2Avm1[1@ -{t<3I6*':2C80`.,1i%N/+/324&'#"&'6326FkȈE338uˇD629DE*O#6 L|FNK-N#3 w ;0;2߲)9-93!Ӝ\C"݃kF%,&m!TUr@ P `  @* H @H   1SؑkAɁ9r$*$@L,0 ID+X߼eԋ^*4Z (eI>9NИfb-@Qg@=EDDOO55_;o;;;@ H;@00888/88 @! `Y' @]Y?3+3?3+3_^]]23+]29/]10"'#"&54632&#"3267324#"'>32#"'.#"#>3237654'.54632bmےlaBHGYPij/aUazLX+-? {}EX)aj>mjnA~u'&3-;D??[;/}!5V[ -"9r|u$*$Kt L)3$(Fm&i hdX@ C$C@>F&+5+5h&j h@ %%>$&+5+5@mY mY  ??+?+310"327#&5$32&RHgd̘I)ֻh 'RHb^@ ]Y `Y??+?3+10#.54$32&#"327=eҘ}3shodc^Ѿ^54/s //10%'%7%7%VH㴁EHJ{J;{Z}9IĤ{PN 0@0/10#"&543!632Y*,Z+-_2 y^(#{sf@ 00/9/102>32#754&#"+7Qys>ao4(+oRd$+$^V"$"%+%yj3 @/104632.yF?+-"+vyx;B*"1-J t3 /105654'.54632wys'$2.;DMsL(2  $&D) (6DR_m@iP4H, B&:V^&,c4k no-&44)"00)d^Wkk`ZggS`IB;PPE>LL7E)`EE`)P     ?o/]2q2/]]3q29///333q2333q2333q29333333102#.#"#62#.#"#>2#.#"#>!2#.#"#>2#.#"#>!2#.#"#>2#.#"#6!2#.#"#>]qO?#&*-O;_;;;;6@3P3333.6-&..&-6  ?/9////////]]93310#67'>737&'.'5467'67".'7&'7 F$a5; Ia4#GA݁hBO݁E?軋Ek(8PC{Lh&ZC7#BO݁GA܂ Ia5; F$a5[8D.^3DuOW.FcB=FKTf".@ mY  ""?22]2??+99?103333##67##! 54733267>4^= nqm=f%"Wcq{-0@-%* @ ]Y]Y?+?+?3922/10!7##"&547332>733#!"&54733267 VfEJW dȬ= ppti~@pNZ0GFvN}~z%"[_T3@mY  mY mY?+?9/+9/3+310)#7373!!3 32654&+#'&)#:1s؉bRob}!?@#_Y ]Y   ]Y ?+?9/_^]+9/3+310!!63 # 47#7373"32654& wjX5lywi!ݩ=Xfj32'"327'7654'], dP_\IL:ZvncHFUa^^9&6viȯ\B ۲kr=S#Jf $@mY  mY ?+?9/3+310!!##73!!D# "#{ mJ .@ _Y 3 I . I  ]Y ?+?9/++3+310!!!##73m!jGfggJTo*@mY mY mY??+9/+/3+10"#!!632#"'532654&\%5!mxsH3`R!bCL9m^ĭ3##틞1Jl.@"  mY?+?3?33933?10!## 333 3# `uftO''HH#^<t@I:_Y"%I,I'I#IO I 4 I/ I<3(]Y#/  ]Y4?3+3?3+3?/?9/++_^]+_]+++q+3+310##"'732654&#"5632333>32&#"327#.547## 5G4/3cge`5>W7df!{P=!+?ccd]FKpLf'"%s i ؿ5D3&|mDV^&|R7"@  mY"??+??3910%3###33ǬuRFF5-+:%95J!@   ]Y/?+??39103 3###3bsPRroJk}#JR7)@    ?3?393939910!###3733)R}{5Hyk}`:CZ9TH-@   ?3?93939103#373%3##'owF#VͶ'JHHsDdZqT5/@mY @H ?3?9939/+3+310!###73733#3{#)&!N{b73)@ _Y ??9/3+3?39910373!!33 ###ŕ))@/1)%Q^)us @  mY?3?+99?10!##!7!3C#-+:%NJ @  ]Y ??3?+99103 ##!7! us!oJ#Tw5 mY @I    "mY?+???39/_^]++10%3##!#3!3dtO}5Vj9J:@# ]Y"I I  ]Y /?+??39/+_^]+]+10!33##!#^bȗrRfhJ7N}JT 4 mY @I    mY ?+?3?9/_^]++10 #!#3!!V쵐}5!Vj9J :@# ]Y"I I   ]Y?+?3?9/+_^]+]+10!!!#!#^b!ǶfhJ7ɚPJTT,@mYmY mY /3+?3?+9/+10632#"'532654&#"#!#!@K ˜s}y{\%5/59 J -@]Y ]Y  `Y ?3+?3?+9/+10632#"&'53254&#"#!#jfL?́D^+*Z>zrL3bƵJ Ĭ#$싞3PJ{-9N@- H ..4+4iY++ ++mY#mY mY ?++?3+9/_^]+999+10327#"&'#"$32&#";7&54632654&#"{*BEI@ZR09[5Wy}<]_$TvȀ!59=oD-k2* ,/)ϾBZQfbbm^+5a@ H ,,@ H,1)1]Y)@))]Y ]Y @ H !]Y?+++?+9/8+99+9+10327#"'#"&54632&#"327&54>32>54#"m|&.5>7Vb\dْeR%HJo^r&H[pr\nRIaZPG Emz;vuzD&&|7bD^&F|} @ "mYmY?+?+3?10!!7!!3#7n# nrO9^81@4412&1_Y ++]Y?2+3/?+?3?931023632327#.547654#"#654#"#33> q{ рT $//pP@EZNwiRw d Dcu^s8nv+$ (o[F0>],sՏ^)vߙ'JZR3<bJ @  ??33?310%673#3}-1fgA k!N媴j'@ mY    ??39/]33+310 3!!#!7!73! ##GJ!i#X)J!@ _Y  ??3+3?3310%673!!##733}-1IJA k!eJ峫"@"  mY?+??39?10!# 333# %S׮tQy/HHJ#@   ]Y  ?3/?+9?10333###춨B9sTE5jk}VB'@ " mY  mY?+3?+3??10%#!!7!!!3sR/n!"leZJ'/@$%$]Y%]Y_Y ?/?+?+?9+31032>73327#.'##"&547!7!BuW}!e "-3pT?>Xdn `&wߚ/! *ocave3y-$@"mY mY?+?39/+?10!#"&547332733#?٨uqR^ӔwRTX4TI&GHP=J+@ ]Y ]Y?+?9/+39/10!67##"&54?3326?33#A&Dj6''FO/ȗrR7yZbNm,IIsN}-@mY ??39/3+310!##"&547333673bB> yw UaJGUT7'0>1.(JGX 7=J%@ ]Y ??39/+999103673#>7##7"&547>?;T-/+h~738JV-Hnuᇉ+FdR@ mY ??39/+103632#654&#"#|ޡ ww S]ZZ2=/.*GI!/99J@ ]Y  ?3?9/9+10!#654#"#33>32=.P \[#V/mJ~}=jW:n{'15@ 'mY+'!!''mY(mY?+?+39/3/3+3106$32!#3267#"47.54733"3 $54&3/K2h^{x u1N?;r[y5-;0"=2&);@h`^HH"P앧X`J^%/7@]Y) &]Y$ ]Y?+3?+9/3/3+310"&547.54673;632+3267"32654&ry+M:"|zMNg-R8g^&R=BK}v`L/%Oݿun9@{+5;@#"))mY/ $!!mY! ,mY ?+?+339/3/3+3?10473;6$32!#3267#&547."3 $54&{1N3/dD^r]JN u?;r[yb^HH"P-f;0"=-&u#;@h'앧X`J^(29@]Y, %''!]Y')]Y/?+?3+39/3/3+310.547.54673;632+3267"32654&Kry+M:"|zMNHg-Rw#ϝ8g^&R=BK}v`L/%D Fun9@ ,f&6fR&+5&6P?&+5T7(@mY mY ??39/+3?3+10"#33#"'532654&Db[}5Zęo}wwq:X/59 5J)@^Y `Y ?3+??39/+3103#"'53254&#"#3b{`ebɊxSF^oJ޴ɪ3=9J;$@mY mY mY"??+?+?+10 3##! #"'532>;vrL343Qh^3`W T 4@   ]Y`Y]Y/?+?+?+993310%3##&#"#"'532>7>32Tɰ%)L^OU[nc2");XQE0Tpxv};W FˉʅA#Tw3 mY@I    mY/2+??39/_^]++10"'5326!#3!3Ӕx~6s}5D15#Vj9 J:@#]Y"I I `Y ?3+??39/+_^]+]+10!3#"'53267!#^b<{b]|}-ZhJ71?JTw5mY@I  " mY?+???39/_^]++10!!#3!33#}5Vj9J<@#]Y"I I  ]Y?+??39/+_^]+]+/10!!#3!33#fh^bȬJ7N}-"@mY "mY?+??39/+10!#3#"&547332673JTr\٨ yw R^ce#X0>1.(HI)'JfJ(@ ]Y  ]Y ?+/?39/+910326?3##3>7##"&547>/Qq4с8JY,mo3DdR'@ mY" ?3?3??+99310!##!3!3##7#'5I?G_VdHX9\J&@  ]Y?+???3993/10!#&'#36733#Ѻfjn"Yˬj'jHJA8MN{ ,f&$6R&+5b&D6J#&+58)&$jFR #&+55bf&Dj 5&+55bb^Tf&(6mR&+5b=&H6%&+5R#5@ mYmY mY?3+?9/_^]++9910"5>32#"&54$!36=4&27# ywhj"Eow+^2&I*'dXa;\"9@ _Y   _Y_Y?+3?+9/_^]+3102#"&54$!374&#"5>267#"ϖO2!zKPd:h. I\ݾvP.&."wp5FR)&jR 8&+55;&j 7&+55)&j=R &&+55&j- Q&+553)&jR <&+55r&j <&+55^0@mYlYiY ?3+?9/+3+910#"&'532654&+7!7!-Վb=O^ϐ"#5v/"-9ot٤yJ=@!^Y   ]Y ]Y?+9?3+9/_^]+310!7!#"'532654&+7!ƌʀΩL ٮFXұ{T&MR&+5qfj&XM-&+5T)&jR $&+55qf&Xj -&+55)&2jR 0&+55b!&Rj 0&+55{b!X|)&{jR 4&+55b!&|j 3&+55s)&jR 1&+55H&jU 1&+55T&M^R&+5?j&\M&+5T)&jBR *&+55?&\j -&+55Ts&SR )&+55?8!&\S ,&+55-)&jR *&+55=&j /&+55To @"mYmY?+?+?103!!3#T5!uR9mJ @ ]Y]Y?+?+/103!!3#9J!jsPJ}T`)&j+R *&+55&j 4&+55of&}D>+5omJA@% _Y 3 I . I ]Y ]Y ]Y#?+?+?+9/++3+310"'5326?##73!!!!3mE*/5*8 ggJ!jGH@wo=8Ԅwo)@    mY iY#?+?+??3910"'532?## 333E*04R`%Sٚ@touy/HȂyoJ)@    ]Y ]Y#?+?+??3910"'5326?##333dD*04*8 RB8@vo=8V5jiԃx-@  mY ?3?9/3+393910##!7!33!%" #Ly^/J=@" _Y 1 I. I?3?9/++]3+393910#73333!##X϶Byⷺj/ V\ @ mYmY?+?9/+104$!33!"&#"!3\=ۨjJbGbH&<@! mY'# #mY ?3+3?/_^]q9/+910#"'#"&54!33327#"3267He)̨JBsU$TL.fqgblPºQRj &KQꦰZgtgbN$1>@$ P ,]Y !]Y!%]Y?+3+?+99?/_^]10%#"&54632367332673#"&'2654&#"!]q\, KPScpBB*ŷ^qkddaxoóc\`}bD/Q_w7}jRlrݟT,E@'iY(**%iY* mY@/]qr?+?+39/_^]+91032673# 4654&+732654&#"'6327ǫnMUbl_d-Ŵ ǺxgK${w`Yk˱=#U6q`eau{^*=@#']Y !!]Y! ]Y /]q?+?+39/+91032673# 74&+732654&#"'632hmBB*ȸWhoP\GJ7Y]fT9ԽVTF^Zcm_g*ƶvrL343Qh^i?pȹG13`W T.@@%$'$!*]Y*!`Y ]Y /]q?+?+?+99331032>73#"&547&#"#"'532>7>32}CY9.*H,̴u%)L^OU[nc2");XQE0Tpxv #2iήE?;W FˉʅA#V;T9@mY@I mY@    /]qr?+??39/_^]++1032673#"&54?!#3!{en^h*ƶ4}5B1qȹFUVj9uJF@-]Y"I I ]Y   /]q?+??39/+_^]+]+10!332673#"&54?!#^b_j#?H+ʹhJ7=Dm7̰AGPJV(@mY mY mY?+?3+9/+10!#"$32.#"3267!+++jFjT.&V/%bd^0@]Y ]Y ]Y?+?3+9/_^]+10!#"&54$32&#"3267!q;+֌DpHc;PN+@ mY   mY?+3/_^]q?+107!!32673#"&547#"lcm ^d-DzB1o̵8_bVBJ*@]Y ]Y /]q?+?+31032>73#"&547!7!!BW9?H+ʹp t#/ep7ʲDFHu)I@*"  iY  "I I  iYiY?2+?+39/_^]++_q+9102.#";#"3267#"&54675.54>{U^QS ܗnRk{wDJA6ytvs7%QĮ"o|e=\o;!+@!mY!mYmY iY#?+?+?+?+10 3#"'5326?#! #"'532>;BugI%,8(9 vrL343Qh^Ȇu=83`W oT)<@ !$!']Y'`Y]Y ]Y#?+?+?+?+993310%3#"'532?#&#"#"'532>7>32R@whF*13T%)L^OU[nc2");XQE0TpxvԄwu;W FˉʅA#&$dbf^&Dd#&$cR&+5bf&Dc&&+5k&$tR&+]55b+&Dt .&+554&$uR&+]55bf&Du .&+551&$vR H&++55b&Dv ,&+55b&$wR2 H2&++55b&Dw D&+55Fs&$'dKFR&+5bf!&D'dK.&+5Z&$xR H H&+++55bf&Dx !&+55\&$yR H H&+++55bf&Dy ,&+55ZX&$zR H H&+++55bf&Dz $&+55b&${R H H&+++55b&D{ $&+55Z>&$'N7Rd&+5bf&D&Nd#&+5To&(db^&Hd{To&(cR&+5b&Hc(&+5T3&(RTR&+5b&HR,&+5Te&(tR&+]55b&Ht 0&+55To&(uR&+]55b&Hu 0&+55T1&(vR&+]55b&Hv .&+55Tb&(wR/ H/&++55bd&Hw F&+55Tos&('dKDR&+5b!&H'd{K0&+5/&,cR&+59&c &+5 &,d)&LdR&2d7b!X&Rd&2cR!&+5b!&Rc!&+5&2twR))&+]55b &Rt )&+55&2usR))&+]55b!&Ru )&+551&2vsR''&+]55b&Rv '&+55b&2wsR? H?&++55bp&Rw ?&+55s&2'd7KR)&+5b!!&R'dK)&+5s&\vR/&+5bT!&]v;-&+5s&\CjR'&+5bT!&]C&&+5&\cR*&+5bT&]c*&+53&\RR/&+5bT&]R-&+5&\d7bT&]d&8dqfJ&Xd&8cjR&+5qf&Xc&+5s&^vR'&+5q!&_vV*&+5s&^C=R&+5q!&_C#&+5&^cqR"&+5q&_c'&+53&^RR'&+5q&_R1*&+5&^dq&_d&<dR?J&\d&<cR&+5?&\c1&+53&<RR&+5?&\R"&+5 5&B!@  /]q2210.'533.'53=.c6''f=<6Jy @ /399/10&'#7673'5673ZaVVW/)1,D7oi=k5:G,u+LB @ /399/10&'#7673%&/3ZaVVW/TZ5B7oi=k5:Ljc) !A@ H  H @ H0@ H /939/+9/+9++103#&'#76%7>54&#"5632W/EZaVDE-'*DS[SI5:7oi=` &%R=:AE)%]@< #   ####/]q3]q2/]99//]3]]3]]910"&'.#"#632326733#&'#76*I#">*3g8*G"#?)2f;NW3 E[`zV3-3,4;/@7ok; h *@ @ /2]22//9/310"&'33273673#zo VN7r!aO+APّwB;}Vw-|& h8@!@ H/@0 /]]22/+/9/310&'737#"&'3327)x@6A!yo VN7sZl]B;} h Q @@% H0 /@  0/]]22/q]9/+9/9/10#"&'3327'#7>54&#"5632!{o VN7THTDC,&%#=N`zB;}AG)b %(R: "X@6  @ H/? /@  0/]q]]22/]+99//33/3/10#"&'3327%"#63232673#"&'&!{o XN6+3h9?Q#@%1i?*L%H~xA8y-3-&:+RD 0 //102654'3#"'7B:=-{(zB/&HBdX%v6qzq o  iY/2+10"'532673FE*7'/6=Dwo4Atu&7zBBD&Wz9=*O@. _Y    ]Y   %]Y?+???_^]+999/_^]3+310"&'###7373!!3>32"32654'_& C''o$-fY_okfbbbZׇ |cò۽hu#R#,B@$$#$#iY$I$$$,mYmY?+?+399//_^]++9102)#"#&5463!2654&+732654&+ۮp|-% '!{ p%1曐qx}ahVo9%-@]Y ]Y ]Y?+??+?+9910"&'##!!3>32"32654'_& CJ!.2fY_okfbbbZY|cò۽hu#J @ mY mY ??+9/+1032654!#332#"&547Dyx73?^XHP?<1"!@ ]Y]Y?+??+910"&54733>3232654&#"״P1 bTheTZJy/ǷGrGyf½)sqys @mY mY ?+3?+310%2$54&#"5>32#"'7\ XiϕJpԺ;!@QH$&@iY mYmY?+3?++102&#".#"327#"$327>E*7(.5:GQft]y4A'-ջ<=+Dwrb#%@ ]Y]Y]Y?+?+3?+102&#"&#"3267#"&54$3276?D+4*11 TvundrI?֓=:/-5@{<}(AP D%@ mYmY?+?+39/10)#"#&5463! 2$54&+{% *®op%1Mb &@mY mY mY ?+?+9/+104$!3!7!!"&#"!3bE6a#!jȢJb#.@]Y ]Y]Y?+?+99?+?10"&546323>!7!#7#'2654&#"V 32">54&}`P˦Ha9f]3bszcV߂XMQr9)_K(A32.#";# 327#"&546?.xߐ|wT]` +״hs)e:T|B0lolyfVï"=o&@mY mY mY?+?+9/+10"&'53267!!!!L"B/*>HX!m "$ NZX쪘5(1@iY (mY mY $mY?+?+9/++10!# $327>32&#"&#"327!/՜yjiޏzeD*7'.5;˸Ǵo^5*!# %Pur4AZݽ%'@  mY?+?39910%#"&546736732654'?2\ozt÷j:dC/6G8̐|df ~]XLi1H9,'@& **]Y*! ]Y ??+???+91032673#"&547654#"#33>32; u#3ѭ @Rx dJX $ Y]~D8p5'bЛ(>3R5uߚ'm>Axgh iY?+?10%27#"&54736W!i&}zu/gEH0s F@*  lYmYI II I lY?+3?9/++++3+3+310)?#73'7!3#p#hi#nd)'ff')T7@iY ?3?993?+10 ##37>32&#"Z{5FoA1/. %D:3}:I? );73@  ]Y?+??399102&#"33 ##>b#C+?Wd%#)%Q" w-p)us77 "@_Y/ I ??9/+3+3103###733\+Շ!#$a@ 8@*H6FV   &$#]Y ]Y ?+?+??9_^]39/]+3999910''7&#"'6327327#"&'&5#%$Y<*DIq %u =!"3A]Y )<;3A{EX Uf@}Bl emkH''@! '!mY!??3+3?3393103267332673#7##"'##"&547+ ZX-ķ WY2˅88,Za62UbtJ̭=@ ;@ mY ??+?39910!###"&'5326733>73}<+!t"B/)?IX ,&{( PXXH]>%9/^{-,@ mY  'mY?+?399+33?10#"$3 >32#654#""32654&qLRgٷ 4򆻣遳T+  V`E<65}fӾb^-2@]Y  #]Y *]Y?+?+99?+3?10#"&54632>32#654#"4&#"326ϔbAP wViXj\nk`YPKL8EI<6cSLu #$@mYiY  ??99//++310!###"#&5463!232654&+#Ńy# ۈ9%1޴zl=!.,@]Y )]Y"]Y?+?+99??+102#"&'##>32&#"3>"32654]+ du y#C+?W/d Zvjgbb\Ʊ`\iQ&웄 {bzejs#T3b.@ mYmY?O  ??99//]++91032654&+ #33 #ʂT5++ukEqg{\'3(*@#&mYmY?3+?399+99104&#"'632327#"&54>7>svg~8\˄8u'D]mv<;oVdLRrCJN\G_nLKMw\F7,>Rfj^&*@$"]Y]Y?3+?399+99104&#"'6323267#"&54>7>VTc/K|`4^fEaU|y2F>GFL~\~Z3%5H3ER&.GY\)"6@p/')(=@# # ]Y#P#`#p# #@]Y]Y?+3?+_^]+91027#"&547#"&54632";654&R6Wg+~~7l|kxB+-1%A '}s>\qdsyh0"L,s1&&%0(,ZD#,@_Y@]Y ]Y?+?+?3+310%27#"'5326?.547#?3!!LSXwiC+7'.0+z~}j72dxr0E|q@RTQNQ)0A@ mY?+3?9/10!##"#&5463!!?MN !oDK%1Z#(@ _Y]Y]Y?+?+?3+310%27#"&547#?>32&#"!!>Si'}%JB?Gz%2xw@RTQPQ)0A@ mYmY?+3?+10!7!!327#"&547Jn# nb0*Q(m J"%a wm)5L"&@ mYmY?+?3+39310%2654'7!!#"&547!7!ϓ|ap>!cfɫ NË'p`ljr@ mY ?3??+10#367>54#"5>323z!Ş^L` 7?\0.O"p|8jmHYD^ !@   mY?+??93310"56323#&"!2EQ[yqw1QWi%H?T^")@ "]Y ]Y ??+?+?3931033>7>32&#"#"'5326?bG hB]J?,)#ZO??ERv6GJK^B9yM ,C쪊gb?@$ iY II  mYmY?+?+9/_^]++3+310!!7!3!!!7!Xoz#ac!sBФ!JI@*  _Y _Y"I_Y?+3?9/_^]_]+]3+3+310!!7!3!!!7#) )1Bɏ{w^D3@lY iYmY?+9?+39/+3107!!# 327#"&54$%#E#cFױ0%rsfSƶ J=@!_Y  ]Y]Y?+9?+39/_^]+3107!!#"3267#"&546$7IqQpǃ}Ͷ~!3L⾡ J$R@0]Y    _Y   ]Y?3+?9/_^]9^]+39_^]+91027#"&5467>54&+7!7!㤖ʟg TxaWF@|p~$|o_]}N +53(4#E@'mYlY 1 I- I iY?+39/++_^]3+3+910)7!7!>54&#"'6323!!fy!ZP`PM\VѢƦ1k`N`:E{ݷ`)@mYiYiY ?3+?9/++31032!"'532654&+#7!HZ&Q_ѕy#C#uϼO.2~"J)@]Y]Y ]Y ?3+?9/++31032#"'532654&+#7!5!kT晴GVwSY9D&6@# #  ]Y _Y ?3+3?3+99_^]104?#?3!!#"&'532654&'.! 'j7)" t]\.DUI<)5QN&,BZ' XbR5N1+Z5\$@`Y]Y???+?+910#33>3276$54&#"PIb}"WMw*6jwŧir`??9/10#3`h';@iY iY ??99//3+33+39/10!3!!!!#!5!5!<<<ğ<7#)3T s&''=VLwR@ !!!>((&+5+5T !&'']VL@ !!!>((&+5+5b_!&G']L@ ///'(>66&+5+5T{&/-T&/M77&OMR{&1-R&1M9&QM&$LFm&+5bf!&DL,&+5&,LMm&+59!&L&+5&2Lm'&+5b9!&RL'&+5&8Lm"&+5qf!&XL$&+5 &8 LZ&@, >/ H/&++555+555qf&X L 1&+555R&8Z&@  1 >4 H4&++555+555qf&X 6&+555&8 KN@&&7 >?555+555qp?&X K <&+555R&8Z&@( >+ H+&++555+555qf&X -&+555;\}&$ LDR&@>' H'&++555+555bf&D L 9&+555&$ Oo@,>&+55+55bf&D N -&+55&MR&+5bbj&MVF&+5P&n@F"#"iY#&mY#- I#) I"IIY I 2 I- I## mY mY ?+?3+99//++_^]+]++]+++3+310!3## $32.#"32?!7!7!/C:yjiuhFMiǴo!ϒ*!# (."2ݽ%3h^$1@U +]Y" ]Y? O _   ; I 7 I 2 I . I ) I %]Y @H]Y?2+?+_^]+9/+++++_^]q+33?+99_^]?10"'53267!7!?##"&546323733#2654#"}Ņ?Kez%A9[]W CAK\uf_YF&0/7Ouj_¾XvަocPs&*LR*&+53h!&JL6&+5T5s&.LjR&+57F&NL{&+5D&2QJbD!X&RQD&2'MRQJ&+5bD!j&R&MQ&+5^s&LR'&+5y!&L]%&+5T &'=VT&']Vb%&G]Ps&*v1R(&+53h!&Jv?4&+5T4@ mYmY@Im??39/_]++??+10#3!332673#"&5475: HJYf$%f}=Vj=%UKbV98' -@  mY mY?+?9+93??102#33>$54&#" :6d d ff]l̛+ֱX<*(rldmzRs&1CfR&+59/!&QC&+5s&$sDR  &+55bf!&Ds 2&+554>&$sR&+5bf&D!-&+5Tos&(s5R &+55b!&Hs 4&+55To>&(bR&+5b&H/&+5s&,sXR &+55j!&s &+55:>&,yR&+59&&+5s&2sR -&+55b!!&Rs -&+55>&2R(&+5b!&R (&+5Ts&5s1R &&+559o!&Us $&+55T>&5TR!&+59o&U&+5s&8sR (&+55qf!&Xs *&+55>&8R#&+5qf&X3%&+53ys^&3@&%&%_Y&& ]Y ]Y ?+3?3+9/+9102654&#"'>32#"'532654&+7Vxb}5[]ɬuyũcӠ\}B+!*(HV˪Vys&+LR&+59}&KL9{'&+5TV@ mY ???+9?10"#33>32#65445! Fи1-yHZdO@bEZ3+(@ mY&mY?+?39/+991026?3!"&547&54?3"32654&쎽!%'=itη %% {NæT7uƳ3\085/mn۰Ѳ}P"1(@ --]Y&]Y?+?39/+99102673#"&54>7&547332>54&#"}"78"sQeUs 77]vps]rtYb2ᐡ&*|ټ} R4>J7\T|tyBj.@  mY  mY iY#?+?+9?+910"'5326?!7!7!!ZC+7'.6z#aqFyj4AwsjJ5&$OR&+5bf&DO3)&+5To&(z{b^&Hz&2 Lm@ 44&+]555b!&R L 4&+555&2 Mm H &++55b+&R M  &+555&2OR$&+5b!&RO%$&+5&2 O (&+55b:&R N (&+55&<MR &+5?j&\M&+5+@ _Y @_Y?+2+99?10632#"&''6732654&#"N*8ixVw09nZy 7@7&73~cyG>Ak;tcB5-13%f9-^)6=@ $$]Y$ 0_Y0 @*_Y?+2+99???+910632#"&''67654&#"#33>322654&#".5gzWv09nYyRFLV~ d Ck}F2E7%73 -~czG>Ak;vc*?Kvߙ'JVV3Nf<;-13*06D';@_Y@ !_Y! @_Y?+2+99?3+310632#"&''67#?3!!2654&#"N3;g{Vq-;oQtj752E7%83-}dxG>32%2654&#""32654OqdV KN+d\ucp]ccM]rq`bb|r[3dżrf{ yfıȕk}Fl{&b^$1>/@,22]Y%99]Y?2+3??39+3102>32#"&'##>7##"&546"326542654&#"Hue\* aT-fZ}vbo^`i]sncda^|k`5ô^^Os,z|cİ`ȕj}%k}ݟfs9@   mY ?3?39/+33999910####373#&5%3/@^l䌵 Lhya9rLjMlM^f&>@$ mY@ mY ?3+?3399+339910&'327#"'#7.5$327"&@-%I"4BUk`VwchfT?-b4 v<= G Vj1Vu$@@!! !]Y  ]Y0?]3+?99399+3999?10"'#&54$323&'3267#"`V q*,53$(^2KI?u lcLqP' (AL7Ù?\ $@ iY  mY ?+?9/3+31033!!!!#^Bm1#9}f#@  mY ??3+3399103###!7!77#>N :n#=Ùf^?V ^ L^79@53(#!.(.]Y*( ]Y]Y??3+?+?3+999910+327#"&'.'.'532654&'.54632.#"  DB54&#"'632aydCոtB}\f{dsϮJ?^'@  ]Y??+39_^]3103>54&#"'>32=|]WDGTu''T֊f+080̭v )i@?mYII2 I- I*! ! iY!I!!!)mYmY?+?+9/_^]++99/++_^]++3+3102)#73!!!2654&+732654&+۫ry-J! ) | n^H›qx{ahD"*@mYmY?+?39/33+33103##"&54?#733!26?!{!/8 }}}+-b MvAA׭՜$n$tiTfoM@ mYmY-@I @mY?3+3?39/+_^]3+3+310)#7#!733#3#!3!3#9mBA5))P#sǵp`1ᡚ^^8 VN&+0I@'.0]Y 0"0]Y%*)"" ]Y?+??39/999+99+9910&5463233267#"'"3274'67#bX&"sΨ;dMQcTwXJf*FA \`VoVD!/,(.!-=sVy+9;#{P$@ mY  mY"?+?9/3+310"'7327#7333#i2EL4"#R{qm{}'/@ ]Y ! bY ]Y?+?+9/3+310"'5327#7333#4632#"&I6:=}+^^%OC6\F/*6CfL9J\F1'81j;lm^ I^h^ `R-m1@  mY   ??39339/33+3310!33###733!ϲy#pw"qD%#7?J#9@ ]Y $#]Y?3?+?3939/33+3310#733!33##"'5326?>7#s6/Xm\ZO??ERv6Gw8BH Nkkgb%Fq+\(/@ "^Y ]Y]Y?+?+39/9+?103>323267# 47"7>54& Hg˦ZZOG7 } ӳbH[UW*MQ0 Z3>}b {xHRbf^D9=^ '@  ]Y]Y?+?+99??102#"&'##336"32654&]( A\xkYgaZ^ȯc[Jߕcxon9=,-@ ]Y ]Y ']Y?+??+?+9910"&'##>32&#"3>32"32654'_& C"v#C+?W0fY_okfbbbZ {T`|cò۽hu#?^@ ]Y ]Y?+3?3+102#"'732654&#"56Ԗ{3wdmgrI?^53 }(A^+4@ ]Y  ]Y @&]Y?+2+9?3+10"''67&54$32&#">32"32654&l;6n=Z!}3shmhMaxRAAaG[t@jPj?t~FrP54HMoMG+3J=29b#0,@]Y ! +]Y$]Y?+?+99??+10"&546323673327#"&54>7#'2654&#"V KZB/6dps ,&`!]phecc´dżrfYA"b!so:Arwhlrbj+.@]Y &]Y]Y?+?+99?+?10"&5463236?>32&#"#7#'2654&#"V !x#B*@W`!]phecc´dżZV uwhlr%^ !(@]Y ]Y ]Y ?3+?+9/+10";74&"&'53 #"$54632Nf?z\LGQY&ʠύ]GY_G#&+%3^;\;h\%.P@+,,)&&_Y))_Y `Y  #_Y?+3?9/_^]33/+3+3+9310273267#"&'#"&54$%4&#"5>267 ./)B&9tuem 䇙Db{KPd:z#I\ð+zWIN۠vI~.&."8h5F=\V^^3o@B 3232]Y`Y3 +I333 I3"I3I 333$ $+]Y'$ ]Y ?+3?3+9/_^]+++]_q+3/+3+99910 54&#"'>3273267#"'#"&'532654&+7TVHP5[d} /.*A'9vs%8T=JRdk#=H##+)[W!{VJNӂ&1$!+-q\VLb1^)O@.]YO ""]Y"]Y?+?+9/_^]]_]_]_]q+910"32654&+73 54&'2#"&54>gr7zzT=+\Z~|UNlq`XFAK~j3хeJ$@ ]Y  ]Y?+?9/3+310"'5327#7333#I6:=}+^^%Cf3j*75@%]Y!]Y  2]Y +]Y?+?+99?+?3+10%#"&5463236?>32&#"#"'5326?2654&#"`_V !x#B*@W/Ņ?K3]pheccwh´dżZV uF&0EJlr3h^ *0@&%""]Y"]Y ]Y ?3+?+?+99?10%2654#""'5326?##"&54632373ZseabŅ?K 3[]W C/!ީޞF&0EujIJewb X(@]Y ]Y ]Y?+?3+9/+10"&54>32&#"327#7!P됦;y# wtp[?yS{fJFJ;-# 9J"@  ]Y?+?39910%#"&54>733>32654'3y[t+N^R ;>@,5?@ sx_;y{%urd[CdZQ4%#\7^ 0$@.]Y")]Y?+?399+310%2654'#"&5467&#"563236?>32&#"*2"q"DnYlTs*16^-b(2B1X15' !#-I89_~W#!tzkYQv{5 bYGOO7) /qfJ@]Y ?2??+910332>73#67##"&547W dc / ZcJNZ0v32&#"3>32W| d"v#C+?W'9 YeY.wݚ' {uj8p9/,*@#(]Y#]Y ]Y ??+?+9?+104#"#>32&#"3>32#"'53276yW| d"v#C+?W'9 Ye%B=>8|*7wݚ' {uj8pĮ;Y) 1@bY ]Y I I ??9/++3+3+103###7334632#"&wjm^C6^F/+79J\)@]Y@]Y   ??9/3+3+10"&5463233##";654&j}o:5wǁ%%J@#`n]f{)1`*?$".7 ]Y?+?1027#"&5473-6Wg+~~`}s7grK2s7D@%^Y  ]Y ]Y?+9?3+9/_^]+3??10!#"'532654&+7!#3ČʀΩLȵLJ ڭFXұ{NqJqJ,%@, '']Y ??3+3?33991032>73#67##"&'##"&547332>7JQy!db / Z\q{ ҀCHNwkJP^*yIrՐ9^4-@.0"-]Y'']Y?2+3?+?399?1023632#"'5327654&#"#654#"#33> q{ р$B=@7{*CHNwiRw d Dcu^sX\ī;^1>JsՏ^)vߙ'JZR3//^%$@ ]Y ]Y??+??+910!#654&#"#"&'5326733>32FLV~ !u#C->*8 Ck}Fc*?KvߙZ 6A#VV3Nf9/^'$@ ]Y ]Y?+???+910327#"&547654&#"#33>32\ZB/6drsFLV~ d Ck}Fb!umB=;c*?Kvߙ'JVV3NfA9J @  ?3?39910##367Z JsaJ1{b!X|byX%_@9]Y"II I]Y  ]Y "]Y]Y?+?+?+99?+9/+++_^]_]+10)7#"&546327!!!!!4&#"326_xڔd?!%Jslj\{re[brPӕ(w\^+-@!((]Y(! ! ]Y!?+33?+9/910%2654&#"32673#"'##"&54$32DŽɶ\w:7 NwЊ 1jiݱĜ׏{ 68QKͪ[]°`ĂbJ@  `Y?+?9?10"'73273#7#5F1'54&j I^i `R-V@  `Y?+?9?10"'73273#7#5F1'54&ʹ I^i `R-J @]Y `Y?+?9?+10"'73273327#"&54?67#5F1'54&jZB/6dps  - I^i #<'b!soD0<`R-o^@   `Y?+??9102&#"#33>F1'81ZuӴR I^h^ u}6`R- o^'@!`Y]Y`Y?+?++?9102&#"327#"&54733>F1'81ZuZA/6cqu I^h^ u}yA$b!um9@`R--^ @  ]Y??3+103>32.#"-%TO)A3(!R^@  ]Y ??+310654#"5632R hDTVa 2"mpE.9)J (@ ]Y]Y ?3?+9/+910!#!2#4&+326J\ȾwafPLJ%3#DMn9J&@  ]Y  ]Y ?+?39/+9103#!334+!26jZihÅ`NyJ3foYJLۏwL^34@1/$*$*]Y&$ ]Y]Y?+?+?3+999910#"'327#"54632654&'.54632.#"YW'a91Q- RAMz~Esk̩:5YXiIlqU-=) d%Eu(0_M7OAH^L+SC7M32&#"G:<51,H=@0EW)!Ǥvs߿1@]Y]Y ]Y ?3+?3+9/3+3103##"'5327#73>32&#"y)G:<51t,H=@0EWi'Ǥvs^(@ ]Y]Y?+?+993310327#"&547654#"5632ZB/6drsZ@16dqtb!umD;<(c!roC32&#"267#"!(yd,H=@0EW@EYygǤvs`\isRuX(@]Y@ _Y?2+3?+310"5>323#7!7!654&97Z g%}j7:{uAPRNVL/89gD"@ _Y@]Y?+?3+31027#"&547#?3!!/=Uj*j76 |tDN+QNQ)5<J"3@]Y ]Y ?3?9/33+33?+910#733!33##7##"&546267!_^\\o Zc5r=NNvi0hηjZ4RJ&@  ]Y ]Y?+?3+393103254&'7!##"&57#7!vYL?Dk"?]٣U3d^ @]Y]Y?+?+?104#"5632!"&547332676d4=K>{ ?gT&@ To|s4/CPaP<寳%.PJ ?3?310#3#.5Bq9R>iJbA>HJ@ ??3?399310%?3#47##'57##33P-  .5#>`zgA s{bL;-Js#@ ]Y ?3?3+?39310!#.5##>32&#"PH a?YQ=?DSv5HJWnca}fJ@ ??393310!#33^}nJ*@_Y_Y]Y?+?+3?+310327#"5467!7!7!!a91Q- #)c 9d%F{HELJ!@@$_Y   _Y !  _Y?3+33?+39/_^]+10!'7!7!7!3>32#72654&#"44y?)cprrFaz!XZ,3bIOeAs{Hϟu6sXC2+TkyJ\J!+O@-&]Y! ^Y    "]Y ]Y?+9?3?+99//_^]9+3+10!7!&'#"&54632654&+727&#"!N=:1)E}§ӗLjWae ۮ}KaRR4?G|CH{lB7;@@ ]Y??+39/3103>54&#"'>32mWADCMdBYr6.5>Qw@]Y ??3+9/310!.54$32.#"'~bMZ5tK} Oޖ6A+7s%@  ]Y ?3+?9/310#"'732654%w~ƇZw|}kOޖvbt)^@]Y ]Y?+3?3+10"&54632&#"3267aB53yVބpvHv5u94-*A '[@=%}Y/O*I"I.I%I?   I mY mY?+?+9/+_^]]]++]++q+10# $32%"32654&4632#"&P􆾤UI-7RF37U* ͑hL^76H`8b\= ^(z@R ]Y /I .I  )%I  I  2I .I )I "I  I 7 I 2 I ""]Y"]Y?+?+9/+++_^]++++_]+q+q+++910%2>5!";#""&54675&54632bp6쁐|:/\RPjeZNOk^AJo4b+2@"']Y"]Y+`Y ]Y?+?+39/+?+10&# 3267#7!#"&54>327>32&#"~zOut@[:?wWgOXW1zgC+4*11 7{FtTC -%&zhws5@9J'#/@ ]Y bY ]Y?]3+3?+?+1046;33##"&4632#"&267#"A!/}uC6\F/*6D5</UWJy9J\32&#"#67#'2654&#"]( !x#B*@Wc /[!Zvi`agIJfb\ZV u54&#"'>323#H!8mWADCMd#!FPBYr6.5>Q2@]Y ]Y ??3+9/39/3+310!#737.54$32.#"3#'H!#~bMZ5tK} 3!FPOޖ6A+7sb&)?@"(_Y''_Y  !]Y]Y?+?+99??+3?+310"&546323673!!!7#'2654&#"V Kcb `!]phecc-´dżrf6χwhlrBFb+.;_@5.-^Y-- --!!&]Y#!]Y6]Y/]Y??+?+99??+9?3+9/_^]+310!#7##"&546323673!#"'532654&+72654&#"9 ɔ`_V KcČʀΩLo]pheccNwh´dżrf6 ڭFXұ{lrbLu'47Ai@:! #@>_Y #A6#_Y#55_Y % /]Y(]Y?+?+99??+3?+3339/_^]+210"&546323673!3>32+'7!7#'2654&#"2654&#"V KcbprrFaz90x?9`!]phecc-XZ+!1^N´dżrf6ϟu6sXW]AswhlrBFC2-MrZqD"4H@' 4' )']Y .._Y 4]Y?+?3+3?3+99_^]99]10#!"&547#?3!632.#"254&'.547!3 yj7EB:5YXiIlqU-PEsk/{2;={uAP@QNL+SC7M32&#"27!ZG:<51 Y }j7'+H=@01)KHU2u xw@RTQNjħ߿k%Q)0AZ D3>\@3&.+._Y644]Y )@(+]Y9]Y ]Y ?3+?+?+?39/_^]99+99+310%27&54$32&#"632#"'#"&547#?3!!%"32654&}3shmgwɲij}j72UxcG[t@}BGP54 p[8xw@RTQNQ)0A17J=29@C@$488 ]Y8#2_Y%2).]Y+)]Y??3+3?3+?3+3?+910"'5327654&#"###"'53267#?>32&#"!3>32B=@7z,FLV{ e(F=>4FV.a_/J?XX a^$;n?Kxݙ'py.KDbʣ'duh|cJjī7)5@(' ""]Y%"]Y?3+?3+39999??10%32654&'.54632.#"#"&'#3lkz~Esk̩96YYgJjpW-ːaL91_M7OAH^L+TB8N:CS_?/7R7 $@ _Y _Y?+3?+3?10!!!3 b rLJχH# I@)   ?33?399//]]99322399310#333 #333-7 +-7 +PP7*@ `Y `Y?3?+99//+310!#!#!#!#3eB5A63eB5B#5#5+}^'(@  ]Y ]Y?+3???+9104#"563232>73#67##"&5476Z@16dqtLV~!eb, ZdIhc!roC<_+wTviFjX<+}^4,@,']Y,! ]Y]Y?+?+3?9?+10%#"&547654#"563232>73327#"&54?67 ZdIZ@16dqtLV~!e[A/6cpt (viFjX<(c!roC<_+w%Fb!rp@4R@  W  T?3??3910#654#"#3>32=q V_$LFAq@gx 01^R-A2nm07@  W T?3?33?3910#654#"#>32&#"632DlVa#Lq\@+7!7pgy<%^tlR~euml.Q!# !@h@V?22?]]107"'532734632#"&4=;0G­;2-+<-&6!Z~`0=0&/<,=@ V TW?22??9102&#"#3>86 ;&Z P 0p @KHs@ T VU?22?9?10"'732673#786 @![P -ks uDO@  VU?22?9?3310"'732673327#"54?B0 >!\P 3059O< cs w^,A}U!% @   V U?3?39/39103#!332654&+T>KI|L^EB7iFHK><3%@  VU?3?33993105#3>3673#@#' B}[3H[a?5@ U V?2?33?393103>3#"'5326?˰9  *Gj>=?45M*3`*21?J 0  //10"&5463"3Mex++5NeM He>++5_.C H >++5_7vt H >++5J ?/10 !wJ-J ?10 vJ+\1?\V@ p/]33103!7373+T+b{{V@ p/]23107#7!#++V{{- A@+   )`/]q3/]33]]]q22/]1073733##7{{ 7@ `/]q310!!R{\# /233103267#"&'' /.)B&:vtem szVJNuL3 ?/1077''7i`Fak^CX{{Xy{VyyV{#@  V?3?39910#"&54673673254''vaOcHXL +-ݼ.ASp`LBm6Q\Hwj4-WI+# T??10#3/}y#W U?33?3310#"'532654&'.54632.#"ît74PQ+TeS3.j?9B+PkTwz;%-71'309lHqB$7, -0++5y9\H{ X?39/310#3XdŚw%9#?29/3103# cęu=/ @?2/]393310%7% X// 1dۓ}/ @/]2?39331077-  g/dܔ}MCCjJ?BSf;?s-f'}R >+5'Z ?55s@ `/22/]10!##Tmsms@ `/33/]10#5#5msm#w; /22/1033#mTm#w; /33/10!5353wmmVc@@0 p/]]210!3!53cnsuVRVc@0 p/]]10!3!cnsVR5 4@ 0@0@0 ?22/]3]22/]q310 5!!Rdy{>!K>ijMP+}/210!!NM$O  jcP>6!S?!LB+?3210#!#GHHHOO <@$  @ H @  '  g w  /23]]q9//+]9/10!"&=73327%4632#"&?uj$A6\E-*7{jO8K\;L2u !@ x  /]q22]]10!2#4&#"?sjI[#zl-++5_Kv H >++5BB<@" ) `pH/+]2/]]2]q3/10373#7#Tᾅ{B%>@# ) `pH/+]3/]]3]q3/10##33 TDžqbj 0/10!#!uX>jgqh ?10376&"5̴>+5hV//33103!7379+T+b{{VZ/23107#7!#-+V{{-F A@+   )`/]q3/]33]]]q22/]1073733##7{{V7 0/107!V'{{V ?2/10"'532673^H3&45: BB|693x=V  ?2/10"&5463327epH=E4.5e[Q @Kzeje>+55~0:PYW >+55;9&?zD.Qp` H>++5B@ 0 `p/]310!#7!#J171b%@  0    /]3223/910#"&'#"5473326733267Ir:KNEao[3L`\3M}Ek=$#G( TBEVBESiL H>++5gK H >++5[N H>++5; H >++5R >+5PeM He>++5 H/310!7!IŃnuR>`/210!!`L/310!7!!Iw++ /3210 L9}1 /?10 #1Dy5̴>+5B@ @0 `p/]210!3!73)J//B\`-P/39/310!!37#hX)-!@0 /]3229210>32632#654&#"#654&#"ln%BpTa n"83Lc#83NnHHTT% !5BE"5BE3 ?1077''7i`Fak`DX{{Xy{VyyV{0@ 0 /10"#72654'&546?I@G#!g7.>8Yrh4#IE&Ts=@0@ H@0/+]10!7!7!7!RR8!C !v0RnW93?5|xU=@ `  /]]210327#"&54?9 %-DGU@D wJH}0/310!#7!#@J1/6Q`t H>++55R@ 0P?]10!#7#{P3{D--3@wx  /]99//3]]3]]10"''7&#"#32732673=7LI]J ,1j7:AB\D'*5lF/}8x:9%s7q3?XBd +?@&!&&&&!!))/))/3/]2/399//3]3]104632#"&4632#"&".#"#32326737=0R9.&2k=/R9-&2)JFC!+2k9,OG=+4mH4@Q1H,&3AR2F,#+#:9#+#5>JZ*w@S!!!!!!!'''$_o   /99//3]]3]]2/]99//3]]3]]10"#63232673#"&'&"#63232673#"'&'+3h9?Q#@'1i?*L%H+3i9:U#@'3h?>^H7-3-*6+.2-*63+?  /329910%377#'3?9/33107#7#5yy3% !'/7AIS]gqy@w  &$622?2O2_2?O[ooVjv~~rzB88F< QeeL` .*0*@**$2jz<`**`32#4&#"#"54632mujI[%C4\E-*7|i73#&'##567&'5s"UXh.9-ig2X)iS3BDM-@+5@  /99//331023273#".#"#>qߞ;n3kj8n&>?}'/'3 @ P /3]2]10 #&!"#6$a)oPxx3ȹt|?/9910!5 5!)!@  X Z[0Y????99//10"&54>3273#7'2>54&#"ZnZ`AOswdF5iA608b9)qt}1)PVXdofY6Ca`tP)} @ [0Y?3?9/10"&54>32#327"2654&R[adkHAMzAc8cy%)wt}\Qv{CF9wTkXE<%5@ @ HZX??+10#3'4632#"&Nu1,#&6"#+5%5#*2%/) [ 0Y??104&#"3267#"&54>32 B9ZvC>ZpXk|Zf~BPJOzn~ws!)@ 0Y X Z?2??910332673#7#"&546{[ HOz @y_rTdX8K!V^jYU/N)@ [0Y?3?310"&54632&#"327VϤfZ1Y6d~GBMbZ){.p'GN/u/) @X   [0Y??]99?10"&5432?3#7'2654#"9^i5Y 0y,l SmVy)yj2-BEA^37qބݒr!5@   0[ X?3?]910#654#"#3632FZ HN~>Ȏ5XwUe58Nwl[[-h5d% @"Z$ !X0[?22?3399?102>32#654&#"#654#"#361#+t@U[ VZ %#As?Z FGp =yXy:?\U2>j8"(2NXe\5s@ Z X0[?2?9?102&#"#36(2)%K|?xS u qZg!)Ff5 ZX?3?310>73#3) ; ɝ[){rV5 @  XZ?3?39910373#'#dᚖb¢Ln39^3?5= /10#5>73*S32#"&532#"&254&#""32654&f*Ne¿?NJR [W]I)y>`fIqS]71o6CejXRbJ #(J?-9P'QT  ?55)&QjR *&+55b^/=@ )_Y) %]Y @ H. H. ]Y ??+?99++?+?+103654&#"'6323327#"'5326?.547SJB4*$+;\;0{=<-+TyiD+7(20 +Vhlk/ZTNZb"NTmws7>BX'@mY mY?+?9/_^]3+10.54$32#"32654&1Ͱ8ҕx5fvz$^+򩑬b!X@]Y]Y?3+??+10#.546324&#"326!fk۹xgj\{rd[ "%՜Ps'@iY  mY ?3+?9/_^]+10&54$32&#";#PҘJ)`3ARH񑡳5b%^&'@# #]Y ]Y /+?399+9910#"'532654&'.54$32.#"(TijѸfIUSgwAmwwFک3lLlk>O8#1t[WG02%'Y]EN, To '@  mYmY?+?9/+9/10!#!!!#! 5!m X8ZJ )@   ]Y ]Y??+9/+9/10#!!!##PZ^?6RD)o&3@mYI  iY  mY ?+?+9/_^]++10!>54&#"'632!327#"&5467%)&*-EJm{#T')#7);Rcr 25S) !k^2h-3]&gW0geZ(4@#%$#$]Y]Y?+?+999999104#"'632%327#"&54675>B1/+IUop@N$:05-8Sn!D;R-5>N;eZ0d}Gse\((0x`9n{Bk]\@    '  @H '@6H?O_  @  T       mY??3+9_^]]]_]]3^]q2+]3233+]310!'%54''%&#"'>328Pa#ZP^NepVJjg`jF7QVHR@1  8 @ ?     `Y??+9_^]]3]233]21067'%4&''%.'51.a/Hcq|B/*Orf0-@"(* 0mY**mY%*?3+3+?3399103267332673#!7!2>7##"'##"&547+ ZX-ķ WY,0#_[~S#@o88,Za62Ubt^͢APA̭=@ )J3)@!3 '.!.]Y]Y!?3++3?33991032>73#!7!26767##"&'##"&547332>7JQy!d$}Ԯ̠%&q{ ҀCHNwkJP^*yV|l߁rDpPh(>IrՐ# +@  mY mY ???+39/+910&#"32673#67##"&54$32Z\leml-[˷i! MsÑ ^/~luJ'h`g˶+3b\ #@]Y ]Y  ???+9?+10"3273#67##"&54632&jVd-ks LX#O))ǣևv'lsl Tq#@ mY mY??9/9+/3+10!#3632#"'532654&#" 5̹δdr~qSN115ߩCN; J$@]Y `Y ?3+??9/9+10>32#"'53265#"#3f@LTWtrn^%1DNC5=/ J5F-.@&&( mY  mY ?+?399+99910"&546323267#"&54>7>54&uϩTYf8yp]]bϩz=s)-#.?Ęxv<3HjQ^g<5`{}B6JgNVm^,.@'!]Y '']Y?+?399+99910&546323267#"&54>7>54&#"ĥOws`kcmkj0kQl98X޷jZ_ƅfq*40+lAQeNNoz6)8@mY  iY ?3+3?9993+9310'.#"'632>32&#"!7 !m<2%)?K32;"@.p+=)#)2QAW#-h1jH?2Z +6{{n++ 32#"54$3 &254&#"XXӅw(H3 )VT«ZPb%vޘb1^#5]Y@I ]Y ]Y?+?3+9/++310"&54$32&#"32654&#"5632(3z\NzE;:O_VVuBV%@  mY ??3+39/3?102#654+##"#&546;3`u7-oƻu NLJqb^B@9\T!"8l7#@ ]Y?3+3??9/10!!##"#&546;3VȷyEPbJLKD'-w^%2]Y@ H$ H$ ]Y ??+?99++?+103654&#"'6323327#"&547SJB4*$+;\;0{=<-+?Jxlk/ZTNZb"NTB-7\#10@ ]Y']Y .]Y ??+?+9/+910654&#"&54632#"&'#3232654&#">O^Ȋe> 'UU{#mIuRv^tg?!ƭ:8K)RYb+ET3.R5b^F'M{b^H\TV=&R@  ?3?39/33310 ##333#6#!5 PиMJcNJ@  ??333?9/310#33#67V%P调#j46%sjj3\&F@)]Y _Y /!@H ]Y?+?9/+_^]3+3?+910#"&'!!#7#73>32%"32654&3XC j#%3ou+P/Dh^o;C5H49s#a@@!}Y/O*I"I.I%I?   I mY mY ?+3?+39/+_^]]]++]++q+10"327#"$32&4632#"&fΖIUI-7RF37)ջ<=+RHL^76H`8s$a@@"}Y/O*I"I.I%I?   I mY mY ?+3?+39/+_^]]]++]++q+10%2$54&#"5>32#"'74632#"&\ XiϕJUI-7RF37pԺ;!@QH%L^76H`8uy%@ 0  /]]9/]10#".#"#>323yXq]*km>mp|N#*#uu%,%4bf^T:uJZ`N@]Y8  ?3?3]9/+10!!#3 .'1z$ !JNTF XJS@3]Y ]Y   "I I I    ]Y]Y?+??+399//+++_^]_]++10)!#!!!!!3#qFX?uJdJJϑL++^+9C_@;!>]Yo!!!!!!! !! 3]Y:]Y,&&]Y *?22+3???+3+99/_^]q+102733>32#"&'##7#"&54$!374&#"56"32654&267#"l*yh^{Q) Ds5ozN1){KP\sXN`bJ5q0D^MN~aŰ^`GZxK~1#Lړbyqosl9DJ$K@* _Y O_Y$]Y?+?+9/_^]_]_]_]33+3310#73!23##!32654&#'32654+`)n9#N}]`vkwdžv;5cxhFAV`bX @]Y ]Y ?+3?+310"3267#"&54$32&wp|D~Jݣx@Ő3NJF;'J @ ]Y]Y?+?+10)!24&+32>q=umtJ̜|5'J g@C]Y*%I? 3I.I*Io7 I3 I]Y]Y?+?+9/++_^]+++]_q_q+3+310)#73!24&+!!32>qcihe?wEDmtՓ̜|9J C@) ]Y"II I]Y ]Y?+?+9/+++_^]_]+10)!!!!!lKAfJJϑuX&b@>_Y +I"!I"I 9 I5 I !$$_Y$ _Y ?3+?+39/++_^]]+]]+q++910#"'532654+732654&#"'>32uT]tJCQDFoHUiZf%~TC*0vgla>C(Ay:AjJ@ bY ??+103#4632#"&!KE30-E0(8J9J4(;M1#J  ]Y/+?10"'532673TU4I:6T"UF6գ95J @  ?3?39910!##3>3^^Zh39VJ6J ,@   ]Y?+?99333333103'737!;J;:{d;BZ!qVJ'du͖9HJ@   ?33?399310!#33#7sw?踑@jJ%t9yJ@  ?3?39910!###3>3 @+`sJ bZZ @ ]Y ]Y?+?+10#"&54$32%"32>54&Z VrhzsoewƮB^wX @]Y ]Y ?+3?+310%2654&#"5632#"'7wp|D~Jݢ賮y@3IF DuH  @aYaYO?99//]++10%2654&$#""$&54632qĿO1ujj^{sd[ݑuH!@aY @ H  ?99//+9+104632'654&$#"#&P63}CB3֓1qjnerqH()3@'$ aY   *)$aYO/]+?9/_^]+9910%"$&547'7632'4.#"6%327@}TgQB}R+Y$r-J"+LecloFcdlp i`6d^ 7;\".8\@83]Yo /]Y #]Y )]Y!]Y?+3?+?+99?+9/_^]q+102>32# '#"&54$!374&#"56254&#"267#" -@ńٓ[JyL-+z}MQyjuty+?\mlatkwyK~/%L):|yp0CBJ*(@((]Y"]Y?+?39/+991026?3#"&5%&54?332654&#"H]t+BP|ٗdkUhZpiV"}X}d_G}, 'eXgU]m'!X@   @]Y?+_^]210#654&#"#6632! xg!⊿EDLRs߽b'@   ]Y?+_^]210%2673#"&5473 {@QJN9J @ ]Y ]Y?+?9/+10+#!232654+XX)Je)`J}}uJ (@]Y]Y ?3?+9/+910 #&5463!##";3\mu{FG"JJ&@ _Y  ]Y ?+?39/+910#";3!"&54673x}d[{l\ͤƦsdJN$EwJ@ ]Y?+3?10!#!7!!(woJ@  ]Y?+?310!"&54733267oQn tcrJ3o1PE/'Yc73H8@ aY aY@ H  ?99//+3+33+3310753254.'%5'#"'7n xݙ'Jvj~Jj<ٴV{ e ZcJ3H$/0M@* aY%% %% aY@ H  20?99//+3+399//_^]2+3310%532654.'%5'#"'2#"&5462#"&546{k"?Kxݙ'J|cJj4@Q1H,*4@Q4E,ٴFLV}e a]R=0R9.&2=0Q=+%17X()_@;& "#"aYaY $# ## #0#`###### #@) aY /3+3?_^]q29/3+33+3310#"'%53254.'%53254.'%5'rT`dY7sԐY/wߘ'Jo| рOuiRve {J  ?2?3103673#{N (6iJwEeaJ@  ?3?3399310!#&5#367373Ӱ+03U+ c^Fk:J{o1!ߑ]J $@]Y]Y?+9?+910)7!7!!Vy;{J;@]Y  ]Y _Y?+9?3+9/_^]+310!7!#"'532654+7j}I\q)VX%*@$"]Y ]Y?3+?399+99104&#"'63232>7#"&54>7>QAO4Ɣ[(XV2[WP?hN6AFFvD35?2>K$E}O^=1adZ @  ]Y ?3+3?910327#"&'#"'73267&54632WU1H4X^|@|[W,7+1XޱAw9gz_h]λܬM;J]Y?+?10!#EȹJLJ/J  ?3?310!#&5#3/P $;eK\koJ;fJ@ ]Y?+?310!#!#!+ȹCJJ9JJ!@]Y??339/3+310!#.54733>73!hD NL be}NNVND/5q2&XPu|qi;J@]Y _Y??+?+10!#! #"'5326!V\tkc;42,>fuVX@0 IN?3?39/]10!#3#.'ˢ)3"W!HDy0@     IN0N???299//]]10!!#!!!!!#@=dEz#^13A/@ I0 N?]?]9/]]q9102#!32654+32654&+tcBSطHcr}ov^Ru{ddQV]Ob]IN?$<@$I I I$$I0N?]?]9/+++33]221023##!#7332654&+732654+Z?طbZov^Rat}u{jL?Tсb]INyZR3@ I0N??]10)32254&+3~dYو ,@  I I II 0N??9/+++]10!!!!!!=dL ,@I I IN 0I??9/+++]10!!7!!7!!{If;P%d#@ J0O??3]9/]10!#"&54$32&#"327#llF^֍7cndqLM< ˶-?A{ (@0I I I IN?3?39/+++10#!#3!3bRbעXX/Zq @ I N?33?3310!?'7!{k{jVXZF @ 0 NI??2]10"'53273HQ,A3r"ѢVT @  IN?3?39910##373\TפecPDAj@jV@@ I0N?]?103!נ}X#@   I  N?33?399]]3103#7##s\Ӣ'X^ZPf @   IN?3?399]]10##3>3ɢ٠")a4oY @ IN?3?399]]10 3#7#3Xלw5נy5 @  J0O?]?]10#"&54632%"3254&~蚹̂훳}viu)ڠӺ)Pဌ#݀F ,!@!I''O?]?39/931026?3#"&5467.54673"32654&Yv+ANН+5 O,y]]}cXkfB#|Vŧ|&VE$'BErM_tPb @ 0IN??]9/]10!##3232654&+9IR BSWXqjNF!@ 0 I N?3?]9/91032654&+ #32#ZxRbRfV휨hcGB)fHJ@ 0IN??]210#!7!! q@  I0O?]?310#"&54733267(ѭ UWlzdALX>=ISx~-#@   IN?3?3399]]3105#3673>3#\'7()9#j[n9Q@NXRli=jQ^m%(@  -  L0ON???39/]9105#"&546?654#"'632%26?y7cEfxc kM'yy hNu No6T<&o] >bAtJpa&'oce3LJ,.%(@K  "  O0L??39/]9?10>32327#"&547"7>54&0gHfxc kM'yy h7Nu No6T7+o^ >bAuIoa*$oce4LK,.@ N K L0O??99??10"&54>3273#7'2>54&#"oydmzC'.tFmB>6ewn`e2?{lT>M꧃&2:@@$.35 -ONK'"0%L?222???399/]210273>32#"'#7#"&546;754&#"56"3265427Cu/hH]n^hqC#r Xs\k VEkrzm?nA4/_F?,VHg7>dXBNbVQJE9{qQ?LॏJA)#@  LFN0O????9910"'#3632"32>54&-zB)&, OdqaAvG>A?h>5bV5p}j[?Ng^GN@N F L0O??99??10"&54>32763#7'2654&#"ixaowF =dXf;<@l@jP/eq{?Njd^@ L0O?3?9/10"&54>32+327"$54& hrrqRJgz6s?p)dX-KO=!t_ +?@ O0L?3?9/102#"&546;74&#"5>267grrqNNgz6s@o)dX-HQ= ov] ,!!3@    -  L 0 O?3?39/]_]_]910#"327#"&547&54632&#";d`_cir}Xf5_XDQ6fC=m^70]ep;u540#-!)@  !!-!!! O0 L??39/]9910254#"'632#"'532654&+7b-_C-yuod{{TZLQ[iIuAfT,3gz3CA<0:}h &!@"K!LO0 M?3??99?102>54&#""'5326?#"&54>3273DrB=@]B|z09Pg%nyludk|C' #o\?TE8&Q`s{l^#w  @ INK??]+]103##"54632^50V;(&2() @ F NK??399?103##37߿ѬP:_1iJR95Lv7# @ K" N0L?22?3399?102632#654#"#654#"#36*nae ^b NRE` IQ"Dcf`=>A;'R=Xdrh @ LKN0M????910"'53267654&#"#363254.&,5u++YF ``orvh2?#K'-iwea,Ouk L 0O??104&#"3267#"&54>32G>fMEbbueuJWԚQUЖ|@ O0L?3?3102#"'732654&#"56ᐓvW%ORmNGYn^'%̖NZ3/5 @0L?210#654&#"#>32G>Q|՗%1.5JWxѠ5 @0O?2102673#"&5473Qyқ M%{؞>*/;QUyh@ K M O0L??99??102#"'#3>"32654&exaj=;7k?vGAB]5l>mC8ncAJ?N`@ 0@K0O??321027#"&546#?33#,ET.deZu \i'R+#v PX#H=y{- @ 0O N K?2??910332673#7#"&547Rc T[ J ,pR^q/8$TLs8Gda88#@ N 0 K?323?9/321032654&'%5'#"'%P&.h4Bea1JAdb++YF*mP`o\Z$ @!N" K0O?32?3399?10"'#"&54733267332673#7^(naf ^c NRE` JQ"C5jg`B83>$RN3:"X>g=6 KN?3?310673#34 bb1^r<j3@ L0 O?32?910327#"&'#"'73267&54632/:#361B[)Hh@B35! G=afy᮰`p:GP1w/Ays}h(0@M!"I"I ""-""" O0G??9/]++9?102#"&'#>"32654&+732654&ǀݘ?a/O%E[1h%_(^o_d59ixCu?7>{b t_P`}ob>Gh@ KNM??33?310#673>3aw5  6ժi[huR\r$&!@"IYO F?3?9]3310467&54632.#"#"&2654'ׯny{=UW%;6 '\ʱ=]nVS.XtfuXp.5'"6 n`Ӟ#vNCRZhJ#@ L0OM??32?10.5467>32>54#"DzzadYB?V{pou?\Pu?L(-h8hg\mSin pdBKh%@M MK0L???9933?1023327#"&/#&#"'6ZRR - 4<5TT ) 3 2Qgd23 q^ktB9X m`wh@ RP??]10#3'4632#"&32T=&%1(9-1'[E6e^R=(USGR?5*aSMR?54W  Q?553SCR?5o#@S0O    Q?]]q?910#"'#>32%"32>54_qrS3%RX5UaP<尲iL`yL~,(.!šun5D9=,9K@'  "&&-]Y&4]Y?+???+9999//_^]33/3/310"&'##&#"#327332673#"'3>32"32654'_& C+4j9/)4lF2fY_okfbbbZC4v4C Y|cò۽hu#b*7I@&&"""" (2]Y+]Y?+?+99?99//_^]3/333/?10"&546323>7&#"#327332673#"'#7#'2654&#"V "+3k9/)4mF`!]phecc´dżIC4v4C Rwhlr5G@$*0 00--6$'$'_Y$ ]Y]Y?+?3+?3+39/99//3310"'53267&#"#32#?>32&#"3#32673#"'bF=>4FV +4j9<.a_/J?XXR)4lFv(pyB5KDbʣ'duh~4C ͽ=^*6?@J$7_Y# 9+7 --_Y!!!!@ 77&3==]Y?2+3?399399//_^]33/]+3992/_^]2+399?1023632673#&'#$'##6733>7654&#"654#" q{ р &L'lKVV_enmM"j;^ Dcu#CHEs~#a^s.OV#f "?&U%ZR3 ^1>J]) &7^#0p@B( (_Y  $_Y$$  @   $ $ .]Y ?3??+99//_^]3/]3+333/_^]+3910>73#&'&'##6733>32>54&#"/6l#}dXV[GlmU j<^ Ck}FhiF+FLe% 66v{f'& S"VV31j&!' 2?K =\*7M@)%$"" "" '2]Y+]Y?+?+99?99//_^]33/3/33?102#"'#32673#"'#7&#"#3233>"32654Y  &)4mF!5+3k9_]skfbb\ȯü14C C4vihu#o^&a@@ H ]Y  @]Y @ H   `Y?+??9/_^]3/++_^]+3/+102&#"32673#"'#&#"#3233>F1'81,)4lFOg +4j:g I^h^ 4C B5 `R-^#f@ ]Y@ H     @@" H ]Y  ? O   ]Y??3+9/_^]+3/+_^]]2/++103&#"#327>32.#"32673#"'-d #5j7#%TO)A3(7)4lFN2E !4C ^04@/'&' !!]Y ]Y?3+?3+99399310#"'532654.#"#>7&54632.#"32673˴AMz~aS_"kmN̩:5YXiTO0:mjH=E(0_MD^Lsr6IL+SCSi' . +3k9;j7R)4mF2xwKB5QN~4C OR!0AJZ@5_Y_Y  @ _Y o   _Y?+3?9/_^]+3/_^]2/++310)7&#"#32!7!32673#"'!)N%;j;?J)-9lHAJ { 3D%< 2E)^ +2@]Y&((" "]Y" ]Y ?3+?+99//99+10"326542.#"3>32#"&'##>dZsbdbǃ?K"3[]\* C0ߒݤ#lE&0|Eujǰa^ +@0 - LN?3?39/]_]]10#!#3!3yHG?b@R)#J"3@ _Y ]Y  _Y ?+9?+9/+9104>7'5!7!#"&"32654&7Ỏ1o_}w~X ?Īvwрsuf=Z@14 88]Y8,03- ,11.!)&)_Y$#&@]Y ?3?3+?3+3?3999>+910!#654#"#327#"'#7&547#?3!!333>321W| d&>Si'Z<}j7}Ti YeY.wݚ' 3N@RTQN?1t~/uj8pJ '@]Y I I ??9/++3+3103###733wjm^ )J.@  ]Y I I]Y?+?9/++3+310%27#"&5467#7333#6W!i&}$]^(zu!`C8s\%,G@(!_Y) I I- ]Y &]Y?+?+99??9/++33+331023##"'###7333>267!"!74cX2Y  dӋ^_o-k$[9\ȯ,,༉1&vi%˲LThuF\J 4@_Y I I!]Y?+?39/++33+33103#!"&5467#733!26?!o_Qn _`^Jr tJCoByC3wo/'YcJ )G@'%_Y I I*]Y!]Y?+?3+3939/++33+33103##"&547#73>7#7!!4&'7!267! r_)нdf%udY+P?o" w2(]8ElΫ99j=$1<@$!  %]Y ,]Y ]Y 0/]]+?+???+910"'5326?#"&'##33>32"32654%F5&45: 8?_& CJN2fYvi7|F_okfbbj69bZY|còhx]hu#bj"/C@']Y]Y  *]Y#]Y?+?+99?/_^]]+?+10"&5463236733#"'5326?#7#'2654&#"V K`@|lF5&54: J`!]phecc´dżcf΁y69whlr0M@,-_Y1@"(]Y""" " _Y ]Y]Y?+?3+?3+3/_^]]++10"'53267#?>32&#"3#!#"&'5326?!bF=>4FV.a_/J?XXV{k$E&44: 71(py.KDbʣ'duh;hy 693^^.:R@/+_Y<@!&]Y!!! ! 5]Y/]Y]Y?2+?+?+99?/_^]]++10"'5326?##"&54632373!#"'5326?!2654#"}Ņ?K 3[]W CVzlF5&45: 8$/ZseaF&0EujIJehy69m!ީޞ7j35@]Y]Y 0?/]]+?+9??1033#"&'5326?##3 3^)o@|l#E&44: 'QJX_.J) сy 69usfFj7%@]Y ]Y 0/]]+?+?10%3#"'5326?#3 Z?|lF5&45: eLтx699j^:F@'4(36 ]Y]Y "--]Y?2+3/_^]]+?+99?3?10236323#"&'5326?#654&#"#654#"#33> q{ рoT?|l#F&44: `CHNwiRw d Dcu^sX\΂x 69^1>JsՏ^)vߙ'JZR39j/^)7@ $$]Y$]Y ]Y 0/]]+?+???+910%3#"&'5326?#654&#"#33>32X?}l#E&44: bFLV~ d Ck}F΁y 69c*?Kvߙ'JVV3Nf=\"/A@&*]Y ]Y     #]Y?+/_^]]+?+9??102#"'5326?#"'##33>"32654rk7|lF5&45: 8AY  dP_]skfbb\ȯmx691&6vihu#jo^ 9@  ]Y]Y `Y?+/_^]]+?+9?102&#"3#"'5326?#33>F1'81ZuLZ?|lF5&45: e I^h^ u}΂x69J`R- jL^2G@'00.#)#)]Y%#]Y ]Y 0/]]+?3+?3+99999910#"'5326?#"'532654&'.54632.#"-|lF5&54: 2?AMz~Esk̩:5YXiIlqU-=Wׁy69 E(0_M7OAH^L+SC7M32&#"%V{kF5&45: 71)G:<51,H=@0EWhy69!ǤvsbjJ)@_Y ]Y  0  /]]+?3+?310%6733#"&'5326?!3qq9C=|l#F&45: = i\EՂx 69J\'jJ4@]Y ]Y  0  ?3/]]+?+9?10333#"'5326?##B8f?|lF5&45: 5ji΂x69VjJ3@_Y  _Y ]Y 0/]]+?+3?+310"&'5326?!7!7!!$E&44: )c 9|j 69{H݂xbjf^#1C@' ]Y ]Y  " +]Y$]Y?+?+99?/_^]]+?+10"&546323733327#"&5467#7#'2654&#"]* A\<F4.8Iep$C^rlYebZIJcb\L @e\&ߕ!byonbjf^bj-:3@#)]Y#5]Y.]Y]Y?+?+?+99?+10327#"&54>7##"&5463236?>32&#"2654&#"NZB/6dps ,&`_V !x#B*@W{]pheccb!so:Arwh´dżZV s]AUlrbj^&09@!*]Y**']Y]Y"]Y 0/]]+?+?+9/+10"&5467#"&54632!#3267327"32654&ep"0Bԓ"y~MQIE4.8g)Hje\ ¼VÇyL~,( @_to5D=j\6h@A#55]Y5 +I555 I5"I5I 555))/]Y+)]Y]Y 0/]]+?+?3+9/_^]+++]_q++910#"3267327#"&5467#"&54675.54632.#";uliLeGE5.8Iep"KJØLMᴼB+Kwg[}jaPV)1 @e\$sKJ'_TDKjV^5m@D$]Y$$$ $4554]Y5 +I555 I5"I5I 555 -]Y ]Y ?+3?+9/_^]+++]_q++9/_^]]+10 54&#"'>32#"'327#"&54732654&+7TVHP5[d}`bF4.8Iep NJRdk#=H##+){o1 @e\$,\+-q\VL;j5\+5S@-0_Y00,_Y ]Y )%_Y?+3/_^]]+?+9/99+3/31023327#"&547#"&54$!3654&#"5>267#"F4.8Iep sDO2!zKPd:h. I\ݾ9@- @e\$,!v4.&."wp5F9j),@bY]Y ]Y  0  /]]+?+?+10%3327#"&5467#34632#"& X9E5.8Iep#e괅C6^F/+7 @e\#J9J\32&#"327epD,0ER,H=@0EW&|F4.8je\#7l}LǤvs@qjfJ)6@!$$]Y$ ]Y]Y 0 ?2/]]+?+?+910332>733327#"&5467#7##"&547W d^9F4.8Iep$J ZcJNZ0vL@e\vi@pjJ'L@+]Y]Y_Y#]Y 0/]]+?+9?+9/_^]+310"&54632654&+7!7!#"'327jdpR|HE5.8jf[$uVrQH/ @@ K N O0L??99??102#"'#3>"32654iz_l|@).wGmBE6b}bVd2@{lX>I䩅B@ L0O?3?310"&5432&#"327tY%OSmNGYn^ '%˗NZ3/jB&#@ L"0O??39/910"''67.5432&#"632"32654|O.i/< tS%UMl\}]j@TV9&?>9G0:VJW'%ʖ\`Net \2 ?)@ $ 0OG??9/9910&'77#"&54632.''2>54&#"d/1P`/=->ÌĢFf!.3ACa7OBcvHL("hB+gb]?r噀<(B~Die/OGE[xFZ X?@  KG0???3210"'53267#?>32&#"3#s81*,,7}|$X&?0.<4XIJJ1Fz sDLAy-X+@   K0??9/3210"'53267#7333#R<-.+":^de==hh\2X?By#y>hh@ 0O M K?2??910332673#67#"&547Rc T[ JA'5sF^q/8$TLEkD=da889 -@ 0  /  NK?]?9/]321033###74632#"&!==hhHJd51T9)&2#yVy):H+;(% K0O??1027#"&5473,?yg2?);hZ% @#M  K0O?32?3399?10#"'#"&54733267332673#>=`(naf ^c NRE` JR E*.)g`B83>$RN3:"X>¯ V @ LK0 N????910654&#"#"'532673632c++Z `g]1+%#+ ``o\K'-;}by5<biwea,OAV"@ LKN0????91027#"547654&#"#3632=+.8En++YF ``on t)HH"'-iwea,Z9 C @  KN?3?39910##37VTnٞ :@&0"III - LO?3?3]9/]]+++10#"&54>32267!4&#"!bueu}IoO(H?Fn!Z|wbQUsHYc[`B'@L MG0 O?32??9/?2210#$473>54'5?D?urqq36 -#' )Tof 3,@"..+'%L M0O?]?3?3993310#"'327#"54732654&'.54632.#"Ǡ55 *,D 95z.KI2GaE~u1+d84>4>`Srw 8:w 0((*2!1)8bCex={%,,!1#6kX G??10"'5327>32&#"J927Q kD1*383Xyt NN}f` @0@K O 0M???321027#"'532?&547#?33#2AB#0/+!3Mt \i'N )#Ϧ{F} -?qH=y0& ! .@O 0 -NK?3?9/]3322?3910#733!33##7#"&546267!^^>>+@;dcI ,pR^qNy%uus8Gda-zsu$T@   K0O??32931032654&'7!##"&5467#7!SGkx86ZX׶HRXgjS_Hmo{\}饊iE{o( K0O??310!"&5463327e9ۄgcF;%e{h'3#9:!@ KO0L???104&#"5632!"&5473326?6#))8?%DɒVTHFTc&  }(y*DnLAFpw(F NK?3?310#3##/b1>`Vy '@K0N?]q9?]q910!7!7!!D^^woyV,@K N0??]q9?]q910327#"5467!7!7!!q7(,5D D^/ 9t=d^wo-y1X!'@  K! 0N?329?]99/10'7#7!7!3>32#72654&#"0o)DLNOS2IW369&#`32'267!"!654|Vua}xVo-%YOLh`{g`\R\h %m @ /329/]104632#"&%4632#"&#.'73=.R;,%154.54>54#"'632)!(!!(!#+#2,.D5h & $$ZUN?  7=   TH-@0  @ H @0/]+]2/]10"#"&547332>;%Qys>`q4(+oRT$+$_V"##%+%@/3]210!7!w%Fjm@/3]210!%7!E%ٚu@/3]210!'!IEߙm@/3]210!'%!EJNw%@/3/2]22/310%7%'#E)FÛw/3/310'%71E)FH   ?9/2102&#"#363' BU{Zi>B l j[{`j \R  /2210.'5673F,z1qKG6 gi D7/g@   ?33/329/310#.'537673%#567&'5#YXi(>*#hg2X)iSC7M-7++59=&EM$ He$$>++5s&&'z%v3R2&+5b!&F'z}vB3&+5T5&'OR&+5b&GO*&+5T&'db&GdT&'ME He>++5b&GM# He##>++5T;&'9b;&G9RTg&'K  H>++5bg&GK, H,,>++5To^&( IR &+55b &H I 0&+55To^&( JR &+55b &H J /&+55Igo&(K H>++5Ug^&HK- H-- >++5;o&(R>+5&^&HR.. >+5To>&('N;Rz{&+5b&H'zN7&+5To5&)OfR&+5^&IO{(&+5P&*M R"&+53hj&JM.&+5Vy5&+OR&+59/5&KOR$&+5Vy&+d9/&KdVy)&+jR  &+559B+&KjPT 0&+55y&+zo/&KzRVy&+N<>+59/&KN>+5A &,R>+5)&LR>+5f^&,?f) H)&++5559& !&+555T5s&.vR&+57Y&Nv{&+5T5&.d73&NdT5&.MI He>++573&NM He>++5T\&/d7&OdRT\&/'dMWm&+5&O'dRMC&+5T\&/M He>++5R7&OM He>++5Mg\&/K H>++5 g7&OK H>++5R5&0OyR&+59&PO4&+5R&0d9^&PdR5&1OR&+59/&QOJ#&+5R&1d)9/^&QdR&1M He>++59/^&QM He>++5Rg&1Ke H>++59g/^&QK$ H$$>++5^&2 HR H &++55b< &R H  &+55&2 FR7 H7&++555b<&R F 7&+555^&2 IR )&+55b! &R I )&+55^&2 JR (&+55b! &R J (&+55Ts&3v}R&+5=!&SvD+&+5T5&3OyR&+5=&SOL*&+5T5&5OR&+59o&UO&+5T&5do^&UdZT&5'dMsR$&+5j&U'dZM"&+5T&5MI He >++5[o^&UM He >++5''5&6O1R-&+5 L&VO-&+5''&6dm L^&Vd'rs&6 C7R 9&+55 }!&V CB 9&+55'J&6 DR; H;&++55 &V DR ;&+55''5&6'O1Rdm-&+5 L&V'Od5&7OFR&+5Z&WOF ###>+5&7dVZD&WdW&7M He>++5D&WMO He>++5g&7K H>++5gD&WK$ H$$>++5&8jiy>+55qfJ&Xjy>+55&8Rp"">+5WfJ&XR $$>+5g&8KW H >++5qgfJ&XK" H"">++5^&8 HR H&++55qf &X H &+55&8 ER &+555qf&X E &+555'3&9RTR&+5b&YR&+5'&9dbJ&Yd!5&:OR&&+5u&ZO&&+5&:duJ&Zd'5&;O?R&+5&[O&+5)&;jR  &+55&[j  &+555&<OR&+5?&\O!&+5s&=K/R&+5!&]K&+5&=dJ&]d&=M He >++5J&]M He >++59/&KM  He>++5Z&Wj@ ###>+55u&ZPb !&+55?&\PG &+55bfJ&DN'&+5m^&AO{ &+5B#4@iY@## mY ??+9/293?3+10 .# #32#"'532654&+sveRȴ81%wDTΝB9VOMNśO.2qzb1&~s9&+5b1&~39&+5b1&~ A&+55b1&~ 9&+55b1&~ 9&+55b1&~ 9&+55b&~ O&+55b&~ N&+55&$k?5&$v?5X'$ ?55X'$ &?55X'$ !?55X'$ #?55Xp'$@ A))>+55Xp'$ A>+55=1&1&+5=1&1&+5=1& 9&+55=1& 1&+55=1& 1&+55=1& 1&+55v'(W?5'([?5~'( ?55'( #?55~'( ?55'(  ?559/1&b$&+59/1&-$&+59/1& ,&+559/1& $&+559/1& $&+559/1& $&+559& :&+559& 9&+55v'+W?5'+[?5~!'+ ?55!'+ #?55~!'+ ?55!'+  ?55f!p'+ A >+55f!p'+ A >+55h31&&+5h1&&+5h1& #&+55h[1&~ &+55h1& &+55h1& &+55h]& 1&+55U*& 0&+55~',_?5',]?5~', ?55', #?55~%', ?55%', ?5fp', A >+55fp', A >+55b!1&RJ%&+5b!1&R)%&+5b!1&R -&+55b!1&R %&+55bA1&R %&+55b!1&R %&+55~#'2_?5#'2g+?5~-'2 !?559'2 3?55~'2 .?55 '2 +?55P1&R&+5P1&&+5P1& %&+55P1& &+55P1& &+55P1& &+55& 3&+55[& 2&+55'</]?5'<  ?55'<! ?55fp'<L A >+55b1&1&+5b1&1&+5b1& 9&+55b1&Z 1&+55b1& 1&+55b1& 1&+55b& G&+55b&f F&+55~A'v_$?5A'vg0?5~K'v %?55X'v 7?55~+'v 3?55+'v 6?55fp'v? A!!>+55fp'v? A!!>+55b&~į1&+5b&~7&+5=&])&+5=&ϟ/&+59/&&+59/& "&+5h&&+5hn&&+5b!&Rī&+5b!&R#&+5P&ĭ&+5P&&+5b&d)&+5b&/&+5b=1&~'s$J9&+5b=1&~'3$J9&+5b=1&~&$J A&+55b=1&~&$J 9&+55b=1&~&$J 9&+55b=1&~&$J 9&+55b=&~&$J O&+55b=&~&$J N&+55&$'k?5&$'v?5X`'$'L ?55X`'$'L &?55X`'$'L !?55X`'$'L #?55X`p'$'L A>+55X`p'$'L A>+55 /1&'b$$&+5 /1&'-$$&+5 /1&&$ ,&+55 /1&&$ $&+55 /1&&$ $&+55 /1&&$ $&+55 &&$ :&+55 &&$ 9&+55v'+'W?5'+'[?5~'+' ?55'+' #?55~'+' ?55'+'  ?55fp'+' A >+55fp'+' A >+55b=1&'$1&+5b=1&'$1&+5b=1&'$ 9&+55b=1&&Z$ 1&+55b=1&'$ 1&+55b=1&'$ 1&+55b=&'$ G&+55b=&&f$ F&+55~'v'_$?5'v'g0?5~ 'v' %?55 'v' 7?55~ 'v'w 3?55 'v'w 6?55f /p'v?' A!!>+55f /p'v?' A!!>+55b&~N2&+5bj&~M#3&+5b=&~&į$J1&+5b=^&~$Jb=&~&$J6&+5b&~R9&+5b=&~&R$J8&+5Z>&$N7R&+5?&$MfR&+5&$[?5&$&?5&$%1 @ /1046327>7.X60-:q?>%5.8C8jK 6,P=]$BY%?5N7Ru +5@ /$)/3333/]99//3310"#63232673#"&'&4632#"&%4632#"&}+3h9;U#@&1i?*L%H;1R9-'1p=0R>+%1V-3-(8+3AR2F,*4@R4D, /&&$&+5 /^&$ /&& $!&+59X&R!$&+5 X&'$R!6&+5'(?5i&(?5'+?5i&+}?5&+5q1 /10#&'73%46327>7.RQ*:60-9q?>%5ٙ.8C8jK 6,51 /1046327>7.673#60-9q?>%5+H?V.8C8jK 6,Zi$'@  /2/]99//3310"#63232673#"&'&4632767.+3h9;U#@%2i?*L%H/0*.=pp%1V-3-&:+%/71YjD 8+h&N&+5hj&M&+5Q9& &&+555Q9& /&+555;$&R&+5b7& ;&+555j>&,NGR&+5M&,MtR&+5',?5i',?51 /10.54632#&'73F30-PZF=%1RQ*45 *K _NTb*ҙ1 /10.54632673#F30-PZF=%10B?V45 *K _NTb*ki%'@ #/2/]99//3310"#63232673#"&'&&54632+3h9;U#@%2i?*L%H<3:*B9#)V-3-&:+(/ DAN*P&N&+5Pj&M&+5P9& (&+555P9& 1&+55531&h)&+531&)&+5P&R&+5l& =&+555>&<NR &+5&<MR &+5'<)0?5'<% ?5-'3[#?599  !@fW/33]]39/104632#"&%4632#"&#.'73=.Q;+%1:0*(;+%1@Q%F94AR2G,*3B-%2G,B?X)99!@ f W  /33]]39/10673#'4632#"&%4632#"&`Xc5T=.Q;+%1:0*(;+%1:~|9G4AR2G,*3B-%2G,{N /10#.'73JV-? U5b=&&d$)&+5b=J&$b=&'$.&+5b&R1&+5b=&'$RB&+51'20"?5s&2P?5T'v0'?5V&vj$?5&v /10673#+H5VZXL%1  /10.54632%F3/-QYF=%145 *K _NTb*+//10#+V!@   //310#'7'77'+V5555X7777  //339210'7##!'77RJ75}o}7L)  //339210##'7!)T77L}57}y5'/3107!y4'_ _  ?3210#&'7!#&'7>> /3/10#!+ToPN) /3/105!#NTP@  //]210###!V @   /33//]3310###!!!VtP @    /3/]2210!!5!###tVPN @   ?3322/10#!#!#sH%sH&sHq #/U@9!}Y}Y ''-}Y{'''T'd''+';'' ' }Y 0 @  ?]+?_^]]]]+99//++1074632#"&4632#"&4632#"&4632#"&@?=BD;=B@?=BD;=BA>=BD;=B@?=BD;=BoBIHCCIJyBIHCBIJDHHDBIJyBIHCCIJ!@  /33/]23103#5!#3###VPPN @  /3/]2210!!!##54#"&54632@i:4<>gAίv~dmNr[`w􉦨#7$!@ 0 !??9/]910>32#"&54632&#"2654#"Je8`ssؔG>;Hp#`N`u-R5A+1}kŒ2y}^.LFGS="%@   0!?3?9/]910#"'53267#"&54>32%"32654&՘F;=S}L_qP`wN`uMg@͓m{jbZ}^}nRHPIU> Q?55Ua4 Q?555UaI Q?55PR @  QR?3?39910%33# #j˸zջw{2Uag Q?55}#F@%!lY$lY lY "lY?+?3+9/+9/_^]3+310)#"&54>32&#";!!!!!bGqy/ghG|Z/ZcX<NFgϽc8:P^oru"*0>@!&-.# #iY iY   !?3/399//92+3+39107&54$?373273&'67##7&'#"&{KD28FR5.F&2uHLFA^+%6M"9O(% 2B "HI*qo@ I$9@"iY mY mY ?3+?3+99/+9102&#" 27#"$32&#"3363.'0$N9HѿJ{v <=&  RH]ɞ9T//@)+@(""]Y?3+3?339?1023632#654&#"##654#"#33> 4 Q_CHNwiHBRw d Dcu^1X\d^1>JsՏR_6vߙ'JZR3#(-e@8),,lY $&&#lY //@H ?3?99//+]q33+33339333+33339107#733333#3#####7%#3!3'#3'67##kCjk#nFon}>y@P!$R{sm;5h9P@*57+&$0+0iY-+iY mY mY  ?3?+9/+9?3+?3+99991032654&+ #! ##"'532654&'.54632&#"}[iq5 thǰr7Agj@NfJ;knGQ=KY@!rnE0w\᝴E(0_M=Y9L[G>TB=T8BN^#'+05;q@>166::4lY($ ,. .+'#lY //@H ?33?399//+]q333+3333393333+333393107#73333333#3#####7!37#37#37#3667#>7#taì˰]q;ĺup:j>32%"32654&2+332$54$#"'>ye|5eK%əSj(ocJT4!VJ>Lol)1$r% htjXrHRz@&"%-h",1@*%lY lY?+?3??+999/310#"'532654&'#.54324#">V=JBCYa`wblZM[~jR!en-km~tǫ}H#)t@E(jY@H )) iY))) )p) )) #iYjY ?/]33+33?+39/_^]q+9/_^]+33+3310#3#+##737#73! 367!!&+267!{ zIud'=HL&! R'>ل1q%pFo#on#Sc$VK@\P!&7@##mY"mY @ mY  ?33+3?39/++3107&54?3.'!+27!ԹPFE[uyj Âz~do^'II J25*!Ø$+% O@,lY lY ? ?2?99//]qq3+333933+3310##737#7!3!#3##! !'!3&uZ)D>9%HN\僨#݃h涭m0i@BlY0-lY*O  #%% mY% mY ?+3?+399//_^]q]3+33+310!327#"&547#73>7!7!654&#"'6323#-!*&u-`GrBvg~8)cf7!ÜH@(lYlY  lY_  ??9/]]+3+339/3+310!3##73 7!7!.+7!{/@$/d?8H IH3rL {bكknK| h"2K@1       p  '/0??99//]]39/103254&+#!2#%4$32#"$732$54$#" SY/^Zm+*լ֭ۢQIE^ZƬ֭+*D 04;@4($! !!!3 ?3?33?99//]]39/333?10'##3'&5#"'73254&'&54632.#"#1n^!f{P'f20Fz.r()"\&9D2?SG}H@36Per)y_,"Bwfum+- 0&YJ/J @]Y]Y?+?9/+103!7!!7!{LVJ_j'V&{u?5>9'&tu?$?5?^Cd^D 1@  p /3/]/93310#&'5673!9>HH>9)DH$HDV @   //293105673&'#DH$HDV:=HH=:#d^D 1@    p     /3//]93310&'3#67!59>HH>9#DH$HDV @    //29310%67#&'53+DH$HDV9>HH>9d^D?@%  p /3/3/]39333310#&'5673!&'3#679>HH>99>HH>9)DH$HDDH$HD(@   /2/29333105673&'67#&'5DH$HDDH$HD:=HH=:9>HH>9H0@   /2/2293333310!!5673&'67#&'5 DH$HDDH$HDhPX:=HH=:9>HH>9G\}d`@ //3993103!!^j8^@   /3/29933104>32#4&#"rуwfŠdHP @@&  P_ / ? o  /]3/]3/]3993333105!5!5!d8d7 @  /3/29933103 %! {RV-*@~Y /_/]q+9/10!!##@  /3/99310#4632#"'&'&#"}?L3% &!" @/)3 )''#i@  //3993103#"&546323265#9P3## #>/'5)%37/333105! h//93103#בK7@ /2/93310!!#'k7n7@ /3/932105!# )@ //3933103!!n@ //3932105!3  @   ///39333103!!#knn@  ///39332105!3# K7@   /32/9323105!!# kn@   //339323105!3! n (@    ///332933323105!3!!# knn6@ _/]]3_]q/_]33333105!5! BZ@  /2/39933103#3#ّiK K >@!  _ /]]2_]q//_]39333310!!!!#'kkב"7 &@   /33/39933310!###ؑ7nn# B@#   _ /]]2_]q/3/_]399333310!!#!!#iro" :@ _/]]3_]q//_]393323105!5!5!# i)ג(7 "@ /32/399332105!### ݑؑn @@"  _  /]]3_]q/3/_]399332310#!5#!5!ӑtt(F(ޑ <@    _//]3/]]3_]q93333103!!!!k#ב $@   /3/3399333103!!33B%n#n @@"      _/2/]3/]]3_]q993333103!!3!!ّJ%i# 8@  _//]3/]]3_]q93323105!5!5!3 iג) "@ /3/339933210!5!333#ؑn >@!        _/3/]3/]]3_]q99332310!5!3!3!5!#LF B@#  _ ///]]3_]q/_]3933333103!!!!#kk#ב" *@    /3/3/3993333103!!#3#Bnn K L@(   _    /3/3/]]3_]q/_]39933333310#3!!#3!!jr " # >@!  _ ///]]3_]q/_]3933323105!5!5!3# iגK &@   /3/3/3993332105!3#3# 㑑iK#K J@'    _ /3/3/]]3_]q/_]399333323103#3!5!#!5!B㑑tK (ޑ B@#   _   /]]3_]q//_]32932333105!!#5! ki"h7 (@    /322/3993323105!!### ؑnn N@)    _ /]]3_]q/3/_]3339933233310#!5!3!!#!5jtrrBޑ"ؒ @@"  _  //]3/]]33_]q932333105!3!5! BZ# (@   /3/333993323105!333! ؑnn L@(         _  /3/]3/]]33_]q399332333103!!3!5!5!B#oV@-   _  ///]]33_]q3/_]3329333332333105!5!5!3!!!!# ikkג#ב">@      /3/3/333339933333323103!!###!5!33Bؑnnnn d@4  _  /3/3/]]33_]q3/_]333993333332333103!!#!5!3!!#3!5!Bؑtr#ޑ" //3310!!V//3310!!V//3310!!V //9210!!+ //9310!!+ *fw% #'+/37;?CGKOSW[_cgkosw{@"2Jjj#3Kk.FVznn/GW{o6Nff7Og*BZ~rr+C[s :Rbb ;Sc&>^vv'?_wwcsgokcgkk`dh_[WW\XTOSKKLPHC?GG@n?o*Z+[BrCs.^/_FvGwA#&.6>JFF'/7?KG"*2:NBB#+3;OCCG@ PQӸCи@ԯ?<;87{{|4xgkosw3ccdhlpt0`OSW[_/KKLPTX\,H7;?CG+3348<@D(0#'+/' $(,$ #  KH@Ԩx`H00H`x DAGO   L/333/3339//////////33333333333333333333333333333393333333333333333333333333333333333333332333103#73#73#73#73#73#3#73#73#73#73#73#3#73#73#73#73#73#3#73#73#73#73#73#3#73#73#73#73#73#3#%3#73#73#73#%3#3#'3#'3#'3#'3#'3#3#73#73#73#73#73#3#'3#'3#'3#'3#'3#3#73#73#73#73#73#3#73#73#73#73#73#3#73#73#73#73#73#3#3#3#3#3#3#3#3#3#3#3#3#fiiiiiihhffffffffffhhiiiiZiiiiiihhffffffffffhhiiiiZiiiiiihhffffffffhhiiiiffffffhhiiiiiifffffffhhiiiiiffffhhiiiiiifffffffhhiiiiffffffhhiiiiZiiiiiihhffffffiiiiffiiiiffiiiiffiiiiffiiiiiiffbbbbbbbbbbbc^^^^^^^^^^^````````````e^^^^^^^^^^^`aaaaaaaaaaad^^^^^^^^^^^`cccccccccccb\\\\\\\\\\\bccccccccccc^```````````bbbbbbbbbbb%```````````bc^``e^`ad^`cb\bc^`b%`C%IMQUY]aeimquy}  !%)-159=AEIMQAS@zKk h| OoLldi}SsPp`"eWwTt\&a# +P;;Xxؿ)H*99]'A!/L?? ,Q<%D.55 &I+648<@DHH0M@26:>BFFA "E/22@6<@ ؾ RS@  $(,0ֹ:>Gʽɹ59ȹ48+/D*.C%)$( !@ ?| {~ osw <knrv ;jj\`dh[_cg@OSW8KNRV7JJDHCGLP@4 kKKk  ׹;?HKO@ 3"&*./333/339//////////333333333333333333333333333333293333333333333333333333333333333333333332333310!35#35#35#35#35#353353353353353353353#3#3#3#3#3#335335335335#3'#3'#3'#335335335335#373533533535!355#%355##5##5##5#353353353355##5##5##5#35335335335#3'#3'#3'#3#3'#3'#3'#335335#3'#335335#3735355#5##5#353355##5#35335#3'#3#3'#3+jjjjjjjjjjjkjkjkjmkjkjjkkkkkkkkkkkkkkjkjkjmkkkjjjjjjkjkjkjmjjkjkjmkk?kkmkkmjkjkjkkjkjkjmkkmjkjkjkkjkjkjmkkkjjjjjjmmkkkkkkjkjjjjkkjkjjkkjjWjjjjkjjkjjjjkjjkjjjjkkjjjjj!c c"a c!b!`````````````b^^^\`h^^^^^^^^cccccccb^^^^^^^^aaaaaaaa^^^^^^^^^^ccccccccb\\\\\\\\cccccccc^````````bbbbbbb bbbbbbb^^^^cccb^^^^aaaa^^^^^ccccb\\\\cccc^````bbb bbb{Z//9910!!{!!@  /2/3993310!!!7L17}1mh{//9910!!hmh{@  /3/3993310!!!hKPb//3310!!L//9910! XVRZ//910 7L//9910 LRZ//9910Z79e-)@  ! /3/39933104>32#".732>54.#"wx{yy{xwV`bcb`c``dyyyyxyy{b``bcbbbV^R'/7?GOW_gow@X\PhhTl8xx<|(pp,t ``$dHH L@@D0044DLdt|l\ JrvNvvvBz~F~~~2jn6nnZ^^RVVVVV:>>> *..v~n^V>..>V^n~v&f0b@bb"0p&/&?&&&/]]/]9///////32]32]3232q32]32]3293333333333333333333333310#"5432'#"5432#"5432#"5432#"5432#"5432#"5432#"5432#"5432#"5432#"5432#"5432#"5432%#"5432#"5432'#"5432377349947575#3773865567557R75577667377349944976#58856556\677675577667667+557775555885Z557w55763:C558337775555776557737+558#  //99102#"54>jmsoujlw)@  //9933103!32>54.#")wvuwwwvu}Bwwwutww)#'@ $%  //933103!4>32#".'32>54.#")R`babbab`Nwvuwwwvu}B`bb`c``cwwwutwwsbu &@   /33/]3993310#"&546324&#"326bcfdiFIKgFEgcIN_}khfJHfFffFHdhy $0:k@%+ 6+:;<51@) H168833@ H(.""O"_"3"3"  /  /]3/399//]333+3]+29333310#"'4! 4#"32#"&54632#"&54632327#"'ybbZٗ31Z-!!--!!-+!!//!!+LL=`bHgj34V// -- // --# #-S@4( $./)--!O_-&+++@ H++  /  /]/99//+]]]32]3910#"'4! 4&#"326%4&#"326327'#"'bc0!--!0.!//!.bb>KLHgj{ -- // -- //ۺ#Fs;)5p@=3$-%-"') 3 3 67"   $'0*()/3/39/3933333333333333310373#'#5&''7&'#5367'767"32654&BAe;-VL12WXByd+N P)opÉ;'--qt>}`+%* J-d}>^1N =LJŇP'$T@+  ""%& /@/3/]99//]333339333333310.54632!!#!5!"327654&qqwTVhL%Xw{TV;>wBh}VTylFFxUVy>=TVwR,8F@#0',!66,'9:,*3$-$*/3/399/99933333310&'&54763327632".'#"&54632"32654&+ !C=#"&5467>!aFXdP{XZ[Xe`Ga^%%`]ZRw;3C@&'. 45*   .#  //99//]99233]3910)7>5'#"&54672&'&5463267632#".'Fw^69Zs\=e% qtET'iCJt8v_=1op#8wL/yuzs3B'$'ykVb'NKuu2Qi}x6fZy@   /3/99910./.54632>32bZ[K6dV'!XaXoV{eAkswwucVB   //9910&'6J{FT+t}FiRmX;.@  //9/93333103#654&'#"&54632Ll^/9r@k99}M+/dyyw {7-NsB@#      /3/933/9333310#"54632#"&54632%%5_s{N/+ىs9:wJ6.'DeQovt5-Luguf7u@E    !       `//]q/9///99933333333333310##57573%377```J`X=@`^``F\^` Z \:@iY iY  mY??+9/39/3+3+3107#733!!!!!!#7'pr?'@=1#`X꒶ݤǑJI@/]Y ]Y  /  /O??9/]39/]3+3+3103###737#7333#wlm&{{?\Z@8lY  @  lY    mY?+?9/_^]+3/_^]]]2/]+103&#"#>32332673#"'!T!.jsZ%,/l5!%^1# .Il3 A6HT9@ mY iY mY ??+9/+39/3+310!###73!2!!32654&+ŃyŢ!NJi!-ۈ9nӴzl##.@mY#mY mY ?+?+?9/+910327#"&547! #'32654&+6(/*Ou|XBϠʂ\%+-' rl&DZg{\ukVy#+>@#*+ ]Y  ]Y +]Y?+?+9+99???10#'#&546323373#7#&#"2654'̐㇍L7 A$eb^r)h\c#+rb9!Z5V8@ _Y@]Y ?3+?3+39999?10%27#"'#&547#?333#>Si'W8ڍ}j7EP4C@RTQN'}Tw9N&@ ]Y]Y/?+???+910%3##654#"#33>32sTW| dJX $ Ye}Y.wݚ'm>Auj8pT5"@   mY"??+??3910%3###373ϑrRA{51}:?}73$@  ]Y?/?+9??1033###3 3^)ݖsTBQJX_.J)%}usfF (@ "mYmY?+9?+9?10#7!7!!#z#aquT}J #@ _Y_Y?+3?+3/10#7!7!!#)coT{H}"&@mYmY?+???+9910"3267654&'2373#7##"5$j0:J˒X̓I+׿ m4Jvi. bP^@  ]Y?+?3?102&#"#3367>K,% 6>A 5L3f^4;J{0<bH)!@ iY &?3?3993?+10#33733767>32&#"#&5&SP> d6) ;'3/wVG #($-jXVh o\إ\XiX  .%?huf^'"@]Y #?3?993??+10#33>3367>32&#"#&573P-  OD#=\*kIL, G-{JPEÕ6x-^L oR&iHh$.@ _Y  _Y ??3?9/+9+910%>3##527&54632">54&GL8he#jy) 34 HV!0rDtcz4TT\1JvG 0T@ mY??9/+10!#3!5BV9bJ@ ]Y??9/+10!#3!BhbJ7b \! @]Y ]Y?+3?3?+10"&547>32'>54#"Ps~nv)zkBPEk󛈗s h|!/10'%'JII)IImmml!` /9/1034632#"&+?,+?:0,?!?#;77;6=8{ /2104632#"&ij>-+?:0->ii<67;6=8@ /3]2/]310!!4632#"&h?>,38:1-=ok;7>46=8j ?2105!53ll3; ?310 !#!b;{ / ?310 !3! }@ ' OG??3]9/10#34632#"&y`HSJ-8RF37XL^66H`7}@)   GN??3]]9/103#4632#"&y`ӶUI-7RF37PdL^66H`7{V9@ (  ??3]9/]103#4632#"&;yfӼUI-7RE38DL^76H`8  ?33210##7##1m21lGmTyT /23210!7373373y1j11lGmSSKz >+5Vg'-o?5HuV@ ~Y~Y/+9/+10!77!i:3 ?9/10 #3y5) ?10#3w}\5'7@@H  0/3]]2/329/+10673#4632#"&%4632#"&wv[%Rq;2R;,&2q<0*(=+%1刋0;2CR2G,*2C-%4E,  :@ H 0/322/]]/329/+104632#"&%4632#"&7#&'53;2R;,&2q<0*(=+%1n|S'^%2CR2G,*2C-%4E,ԁsh $@mY mY?+9?+9107! !7! #]#Crlq3 /2106$!"xyős}J3 /210 #&!a+kO3ɸ  /22310.#"#>32[k8o'ƌiY'&  /33/3103273!"&'\k;objX'' $@ /3/99993310!#!5!3d+\+ $@ /3/99993310!#!5!3d+%F $@ /3/99993310!#!5!3n!ZZ @  /3/999310!#!5!3n!DN @ /3/999310!# 7 3g\=H`3R "@ /3/9/3993310!#!7!3bH3o`RN @  /3/99993310!#73^J^sN @  /3/99993310!#5 73gRۇjh0hF@  /3/999310!# 73qZyfkFq @  /3/99993310!#73q_ZGd)5 @ /3/999310!# 7 3RkGHyN!5 "@ /3/9993310!# 7 3Rk`/L-!P "@ /3/9/3993310!#!7!3ysdH^- @  /3/99993310!# 73`wcFFH@ /3/999310!#73vq=Df-q @  /3/99993310!#73qFsGVH!% @ /3/999310!# 7 3>{GHZ1#% #@ /3/9993310!# 7 533X3'5g% #@ /3/9993310!# 7 3D{rVJ1}q' "@ /3/9/3993310!#!7!3by R1X/@  /3/999310!# 73HՇH7%q @  /3/99993310!#573q>{G\1# @  /3/39999310!# 7 36}MH)R/) $@ /3/39993310!# 7 530XAuP/j5 $@ /3/39993310!# 7 3NN-qT+o5 $@ /3/39993310!# 7%3Nu7T+}/@  /3/399310)733+NT-)q@ /3/999310!#73qB=T-)P@  /3/999310!#!'!`sboL #@ /3/9993310!# ' 3\H6fy3L #@ /3/9993310!# ' 3VH)hy?L #@ /3/9993310!#5' 3THhy-^ @ /3/999310!#' 3P5fy=Lq@ //9999310!#'3q^hy"@ //9/3999310!#!5!3qT; &@ //9/399993310!#!5!3`/h{T &@ //9/399993310!#!5!35%"@ //9/3999310!#!5!3@P@ //999310!# 7 3i``ybVL "@ //9993310!# 7 3e`;H`FF $@ //9/39993310!#!7!3gb+\t]^L @ //9993310!#73^'ezL@  //9999310!# 73e\هseRdZLq @ //9993310!#73qe^=ddZ/@ //999310!# 7 3Hu7T`H?9 "@ //9993310!# 7 53Ru9HpHF? "@ //9993310!# 7 3Mw\sX=T9H? $@ //9/39993310!#!7!3lwo V=1?@  //9999310!# 73\w߇5:=?q @ //9993310!#73qXw1-B=+5 @ //3999310!# 7 3N}5H)1q5 #@ //39993310!# 7 53N}<Au1]j5 #@ //39993310!# 7 3NN-q -+o5 #@ //39993310!# 7%3Nu7 -5@  //3999310)7331N߇ -P5q@ //9999310!#73qN3 -yL@  /3/999310!#!'!nwJ{L #@ /3/9993310!# ' 3nH J{3L #@ /3/9993310!# ' 3nH)T?J{?L #@ /3/9993310!#5 ' 3nHu^J{-L @ /3/999310!# ' 3n5RjJ{=hq@ //9999310!#'3qo;L{L@ //9999310!#'3kNf{F $@ //9/39993310!#!'!3bj\L "@ //9993310!# ' 3\H5gyFL "@ //9993310!# ' 3VHiyPL@ //999310!#' 3ifrq\%Lq @ //9993310!#'53q^g"@ //9/3999310!#!5!3XV9ZB^ &@ //9/399993310!#!5!3cf)9% &@ //9/399993310!#!5!3b-%w"@ //9/3999310!#!5!3ZV@ //999310!# 73f^ q%^`V "@ //9993310!# 7 53o^h^xX "@ //9993310!# 7 3q\3Hmg1ZV $@ //9/39993310!#!7!3bL+Vm\V@ //9999310!#73'^{^\q @ //9993310!#73qu\/3g7 @ //3999310!# 7 3=q+\=LD7 #@ //39993310!# 7 53Po+^-L i7 #@ //39993310!# 7 3Po?J?LL)7 #@ //39993310!# 7 3PqX/XLBb7@  //3999310)7331PqLb7q@ //9999310!#73qPq?L{H@  /3/999310!##'!y\1F #@ /3/9993310!# ' 3{Ny1PF #@ /3/9993310!# ' 3{Hb1F #@ /3/9993310!#5 ' 3{HtD1\F @ /3/999310!# ' 3{HX1)Fq@ //9999310!#'3q{91@  //9999310!#' 3wbL^=5 $@ //9/39993310!##'!3ws;s=9 "@ //9993310!# ' 3uHXqHETJ9 "@ //9993310!#5 ' 3uHHG}9@ //999310!# ' 3uHHG9q @ //9993310!#'53qw>K@  //9999310!#' 3[VHZdbVs @ //9993310 '53#/[{b $@ //9/39993310!#!'!3[HVbk^ "@ //9993310!# ' 3[VHB1by@ //999310!#' 3_VHLdy}Lq @ //9993310!#'3q^d+"@ //9/3999310!#!5!3LR= &@ //9/399993310!#!5!3aNA%1o5 &@ //9/399993310!#!5!3qÇ"@ //9/3999310!5!3#d+VL @ //3999310!# 73e\-yfL #@ //39993310!# 753e\ }VyfL #@ //39993310!# 7 3e\j?yf)L #@ //39993310!# 7 3e\=J3yf6P@  //3999310)7!31i\y whPq@ //9999310!#73qi\;wh/@  /3/399310!##'!l-T5 $@ /3/39993310!#%' 3H{-T75 $@ /3/39993310!# ' 3HJ-T+ $@ /3/39993310!#5 ' 3H/P% @  /3/39999310!# ' 3}H)/R))q@ //3999310!#'3qÁ)-T/@  //3999310!#' 3TH7H' "@ //39/3993310!##'!3eyT19% #@ //39993310!# ' 3{Nq}1JV% #@ //39993310!#5 ' 33h5@% @ //3999310!# ' 3{H#1Z%q @  //399993310!#'53q{Šy1H@ //3999310!#'3vfD=- @  //399993310!#' 3mwbFFcP "@ //39/3993310!#!'!3sXdH^5 #@ //39993310!# ' 3kL!-L5 @ //3999310!# ' 3kL!Ny-q @  //399993310!#'3qs!HVF@  //3999310!#' 3RZZjfyN @  //399993310!#' 53LRHh0hjN @  //399993310!#'3}^s^JR "@ //39/3993310!#!'!3bqlV`sN @ //3999310!# ' 3\H3`Fq @  //399993310!#'3qZ)d @  //3999310!#!5!3D $@ //399993310!#!5!53'ه) $@ //399993310!#!5!3sD $@ //399993310!#!5!33\+Շ\b&~ ? K&+555b&~ @ 3&+555b&~ A 3&+555b&~ B 3&+555b;&~ W 2&+555b;&~ V 2&+555b;&~ U 2&+555b;&~ T 2&+555h& ?n -&+555h$& @n &+555h& An &+555h& Bn &+555h;& WQ &+555h";& VQ &+555h;& UQ &+555h;& TQ &+555P& ? /&+555V& @ &+555P& A &+555P& B &+555P;& Wy &+555P;& Vy &+555P;& Uy &+555P;& Ty &+555h& SY*&+5555h& RY*&+5555h& QY6&+5555h& PY>&+5555P& S,&+5555P& R,&+5555P& Q8&+5555P& P@&+5555T}V -@  mY mY"?+?+??9/39/10"#33>32#"'732765445! F&׳j2EO/-yHZPO@R} F(0@   mY#mY?+?+?9/9/9/3104#"#33>32#"&547332676yԖ F^:(\?)yC_BNNHRtLq,&@ ]Y $]Y$]Y$?+?+9/+103265!#732654&#"2#"&547>=vrA!Gkau$iŲ~!`7}arv?&|װ P%@ @ H/3]3/+]10#.'73%46327>7&!!BR(E960-:t?>ZV'H8.8C8hL 6 #@ @ H/3]2/+]10!!46327>7&673#)'ٔ60-9t?>Z+H?VZ.8C8hL 6Zi P!@ @ H/3]2/+]10!!.54632#&'73)'#F3/-QYF=%1RQ*Z54 *L _NTb*ҙ !@ @ H/3]2/+]10!!.54632673#)'LF3/-QYF=%1+H?VZ54 *L _NTb*Zi;! @ @/9/3/104632#"&>73#<0R9-&23-(Hqb4AR1H,D7E34H E@)IY8o@p  /]q]2]2]]9]/39/104632#"&3673#&'`<0R9-&2m[Qlu+?(X4AR1H, Jq`[&anT@ /3]2/]33310!!4632#"&%4632#"&'H<0R9-&2q:2*(=+&0`4AR1H,*3B-%4E,o ,-@"(0@(($/99//3]2233104632#"&%4632#"&"#6323273#".<1R9.&2q<1*(=,%1'2i=/G<8 K4iR-D;9X4AR1H,*4A-%4E,);%en|$bG,b@o -@ 0@  /99//333/]q10"#6323273#".7>73#'2i=/G<8 K4iR-D;96i-"Vr;);%en|$?|E,<# @   /3]3/]10#.'53!!n6s&H(q':CDDs9  @   /3]3/]10673#!!bdh-Br'u:-X?%S@5@p` p    6'#/3]]]22/]]q]]q29]/9/103673#&/4632#"&%4632#"&lD^z|tz"[+0;2R9-'2q;2*(=,%1?6mM,_B2CR1H,*2C-%4E,9(@ @0 /3]]2/910!!4632#"&%4632#"&'1:2R9-'1p;2*(=,%11DR1H,*2C-%4E,u3@0/?   @ H /+99//33]]10"#6323273#".!!+2i=/G<8 K4hR-D<9y;13%em}$u#@0_o /3/]]10!!4632#"&'{E4^F/*8:I\%1+H?Vu822870: )L `MTb*Zi); &5@ #@    w  /3]]]]22/]10!"&'33267.54632#&'73Ao NYU^F3/-QYF=%1RZ!u8228745 )L `MTb*Ҫ); $5@ @$$$   w  /3]]]]22/]10!"&'3326746327>7.673#Ao NYU^70-9q?>%5(J?Vu8228%.8C7kL 6,Si); $5@ @   w  /3]]]]22/]10!"&'3326?#&'73%46327>7.Ao NYU^;RQ*970-9q?>%5u82283.8C7kL 6,+@mY mY ?3?+?+9?10!##! #"'532>!3%TvrL343Qh^y 3`W /HhT$9@"! ]Y `Y?+?+9933??3910"#"'532>7>323##&L^OU[nc2");XQE0TpxARB8ۮ;W FˉʅAnV5T-@ iY  mY ??3?+9/99+3103 #!##!232654&+y)y5Jۈ9*(HŊ޴zlT\'3@   "]Y  ]Y?+??+93??31023 ##"'##33>"32654F#AY  dP_]skfbb\ȯ㼉1&6vihu#K@ mY mYmY-@I mY?+??99//+_^]++9+310)##&54$)!!!!#";5#` q1^g8wx^3;E^@3?)]Y "??""<]Y"99]Y994]Y]Y1-]Y?+3??+?+9/+9?+9/99+10"'##"#"'5326767.5463!632!#3267";%"32654&La]7M<):N`C2"4F.Hs_`w#z~LR`nvѴLg)I{!FUx\, F`*]i}yL~,(,#g[fun5DT7@     ?3?391073' ##3'7wF5ouX%+:xY9DJ@ ?3?3910##3'773Ӯnrqybo}bٮ#JKP/+4@mY**mY* %mY  mY /3+??+?+9/+10632#"'532654&#"#! #"'532>!@I ˜s}yـ\%vrL343Qh^/53`W  T5B@$/ "- -*3]Y]Y3%*`Y% `Y ?3+??+?9/++993310632#"&'53254&#"#&#"#"'532>7>32L?́D^+*Z>zrL3b%)M^RQTqe2"):VOJI_kcvjĬ#$싞3>Z Bֲb/##?@ mY mY @I   " mY /3+?3?399//_^]+++10632#"'532654&#"#!#3!3#@K ˜s}y{\%}6/5Vj9 J$E@*]Y!]Y!!"I!! I!!# `Y ?3+?3?399//+_^]+]++10632#"&'53254&#"#!#3!3L?́D],*[>|oL3cg9h^cjĬ##펛3J7T{ @" mY  mY?+?+??10%##!#!vQ}59F^&@ ]Y]Y/?+???+910%##654&#"#33>32FsRFLV~ d Ck}Fo}c*?Kvߙ'JVV3NfR%@ mY  mY" ????+9/+104&#"#36323##6S]Z5|ޡ TwRw GI!/9Z@/u/.9F&@ ]Y]Y/?+???+910%##654#"#33>32FsRW| dJX $ Yep}Y.wݚ'm>Auj+e@    /322/10#'##'##'7v!H!G#+ ggggTU@6_o   sY??+?9/////_^]]9910%%2>73!"&'??3 2#1-A~32!Ps FFEFtu=G@"G.;@s{1#G/@}G0@G@#G@ ^ ^  v L &  "  D. *r ( \ >  <^  40Copyright 2012 Google Inc. All Rights Reserved.Noto Sans UIItalicMonotype Imaging - Noto Sans UI ItalicNoto Sans UI ItalicVersion 1.06NotoSansUI-ItalicNoto is a trademark of Google Inc.Monotype Imaging Inc.Monotype Design TeamData hinted. Designed by Monotype design team.http://www.google.com/get/noto/http://www.monotype.com/studioThis Font Software is licensed under the SIL Open Font License, Version 1.1. This Font Software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the SIL Open Font License for the specific language, permissions and limitations governing your use of this Font Software.http://scripts.sil.org/OFLff  34566778:;YZ[\_`ders}~NOGHTU > ? W X o 45Z[  `bddss!#$$%%&()+,-/1256689::BNHIJJKQRRSSTT Ncyrlgrek$latn4 kern8kern>kernDmarkJmarkPmarkfmkmk|mkmkmkmk        *:JZjz  & ' *h ,J A Rt S `( ` d  g\h dF`bddss  %(3!-:/6G8:OBNRHT_%$=D]4KBj77NNSV\_27 BI^alq~!WYZkl""(UZW]f]kngqk{QQbhssvvl $*06<<BBHNTTTTZTTTTTTTTTTTTTTTTT`fTTTll rxTx`TT~TT*TTTTTTTT &,28>DJPJPV\bhntz,J nt,"(.4:@:FLRX^@djpv| ^p@ <$*06*<BH0N$TZ`fl$Tr$Tx~v&,PPPP88>Dntntntnt:P@@@ &@,@28@v>DpvJJJPV\VbVbhbntz    , X zzz&d&@@\2|\\P\ >Dn 8>D PPP"(.4P&\:@F\D@L\RX@V\^d@ntjphntv|8,X@ $*06<B  H NTZ`flr0Jx$~ 0<64r B~0 B0ntXntntXt ntXn&N,2.48>lD:J&PV:\LRbLRhnLRhtzJ.4>l2.4>l.4>l:&x0tNj @J"( P.PP4:@FzLRX^djpv n|Nj:$&xx:&x BXj&,24j8DXj|8>D :L  rj$*0f6<BHNT@Zlr4`flPrf*x&2X~j@<4@zB8z P00"$FLR~n|  &,28>DJPV\bhntz&@z t&~rp  "(@n.P4n.P:@FLRnX^djpv|b :n@@:(PPPP&|  Dr :Dl0$t*06t<0BHNTZ`6tflrxt~F~@Jn, 0xB &, 286~r>DJPVJ\Dntbhntzp0|JD$0$xPX@&jX&jp|$|||~  p@$&N$6< HZ"(.4(.44PP:@&vFDLxRXJX$~$~b^djX@@6pvpv|pvBNjPrr*xrZ~n~n~~>J0zXpn|@6$0>  T     $ * 0 60 < B H N T ZN `N `j f$~0 l<B<~n r~ x ~p (  Nj   p@P   f  $~, l~, $ $ ~n ""  , $ X~  N n !d!j!d!!!!!! >!& 8>!,d8>!,d8>!2!88>!>!DJJ!J!P!V\:!\@nt!bhn!hnthn!nPhn|z!t6!z!,"!@,!!,!!!!!!!8!!!!!!!!F!F!L!!! !!!~0J!,$~!J!,$~!V!<!6"4" <"""""r"(4!"."!J"4":0 "@B"F B"L  B"Rn"XNn"^N n"^N "d,""j&Z,"p&"v"|.4">l(."`>"":@"&r!J:@"&r":"j&x"dLR""FL"~n"FL"~n"! ""l""x"@"X"TP!J"z" &<"#D:~:OE~< LfdtL~~~(<\L  X44XG|FDD|G P <ll:g+:}j0II0vhv\Xh8DDhx8hQh,lh|lLAvNQ hbl0~Rllplp4lHLl@bllx@\D@D@@@@v@v @$lll,nn4X, :,: l D,Xl<nH8>l\lfv,<T@l@,@lT,G<<,|pnl<<Dh<|h<,~<<n4`,40< <,pX,,H@,> ^> 0 v vLxu<<,l,llIv0,\hP<%@ @l@|T@@$(  lP D ^NP @\ <P  vLPv jPXlvbHh`h|,[|,l vx0,hTtN!!5b&5D n,N@0@Fp<f 8p$,@ ,X@,*,@J{55II,*@<g q&r0@X,l?l,,@D\,j,@l  (,b@(,"\"n,,hMpjplfllhhlXlh%\ p\ThnZ%Xpphkzd~r,TG0,o,$ms| <T,h@@jVhhhnJDddVt]ItE R#Nrlpp@ppp;I|pp~pp|HHHH&vTlDD>>DpplHRlapp@NXplhpl,1pvX@@4vl,ThTppllKlbl@%ddK 0 Pb`aHHNTHNTZ`flrx~vl0l\ll: zb+D,,,Xh $=D]4;CHNOPQ?ARCCUGGVJKWMMYSSZWW[YY\de]xy_{{ab &,28>>>DJPV\bDhnntzhJDDDDDDD\\\\nnnnnDJJn`~u~uj5&F~B~x`~JH-)pH@JpJT JJJJJfJ<J6hH* ^J,JrJJ X^ $=D]4679;<*+>FI@^aDH "(.4:@"(FFLRX(^("djp"v|v^^^^^7xx!wJxdxyX8$*8J\#apMJJ@R%FJJJ`J@J ;A$=D]4KBj77NNSV\_q~]""eU&QQ'bh(ss/vv0   1      & , 2 8 > D J P V \ b h n t z  "(.4:@FLFLRXFL^djpv|            P P P P                    "(.4.4.4.4FLFLFLFL$*jpjpjpjpjpjp       "( "( "( "(    .4 .4 .4  .4 .40 80 80 8 2 86 D< > D PFL PFL PFL J PFL PFLBHNTZ \FL RXRX` hfL b hFL b hFL b hlr b hFL  z  x~ z  jp jp jp v| v| v|                    FLFL t^d                    .4 .4 .4 4 4 4 4 .4 PFL J PFL jp jp p p p p jp           &&&&    ,2 8>   "(  DJPV\b  hntz & ,0 8  J P RXFL z    \b   tz"(.4: @FLRX^djpv|T   PFL jp  2 8 0 8 X jp jp FLRX^0 8      .4 .4 PFL PFL jp jp v| v|  tz b h6 D<     .4 jp    $*$*  "( b h 06<B  .4 V \FL v|   "(HNTZ`flrx~FLFL^d^d^djpv|v|v|v|:@:@ & &,2,2FL,2jp 8>DJPVPVPV\b hntzFLRXPVPV.4$*:@^dv|:@ FLjp"RXFL^dv|(.  .4`flrFL"(,24:@    "(          4 4  .4  .4 .4F ,L@0 86 D< > D6 D< > D > D J PFL PfL X RX RX b hFL` hfL b hFL b hFL t^d n t^d  z  z  z  p p p pR R  v| v| v| v|      X       < <^    d d    Xjp v4:8> b hFL b h  |<JJ(JVVmmqq//  jjjj77??//uu00000V000j00m0q00!,!/000``//0 000?0DDhh0h0h0h000\\ooJJNN}}  ``##//XXRR;;==jj 0 11!0;0 //  33}}hhmmXXZZ}}``NNPP--??TT``RR++HH33ooJJXX;;00000j070hhD0oo $=D]4KBj77NNSV\_q~]""eU&QQ'bh(ss/vv0   1      & , 2 8 > D J P V \ b h n h t z h h h h h h      > > > > V & b b b b b b n t t t t h h h h h h b b b n n n n h h t t t t t h h h h h h             h  h  h  h , , , 2 2 2 2 8 8 8 > h > h > h > h > h > h J V V \ \ \  J J J V  b  b   b b b b b b b b b b b b t t t t t t t t    b  b  b  b  b > h > h           V V V 8 h  & h " , n ( . h 4 : @ D F L  R X  h ^ d j h , 2 p v | 8  4   \  @    &         b  > h  2 h      h    h b b t t   , , > h > h @  h  h   \ b t V     n  8   > t   h , V  b b h n  h h   $ * 0 6 < h h B H h h h L N T Z ` f h h l r x ~  z z      h          <    h       R     t   h h z h h z h  B  L h  h h  h h  b b h t * 0  n  h  h h h n h h h h h t t t t t z h h h h h h          h  h  h  h & h & h , , , , 2 2 2 2 2 8 8 8 8 > h > h > h > h > h D D J J P P V \ \ \ h b  "   & , b   8J0000V000m0q00/0000000 00j0j00700?0000000000/0u00000000000!0`0/000D0h0000\0000o0J0N00}000 0`0#0/0X0R00;00=00j0 00100000000/0 000000300}00h0000m0X00Z000000}00`0N0P000-0?00T0`00R0+0H0030o00000J00X0;000o0 Z`"$&(*,./125678DFHJLNOQRUVWXL"LRX^djXpvj|Xd Bv&le_^\Z! ^ $=D]4KBj77NNSV\_q~]""eU&QQ'bh(ss/vv0j1jpv| $*06<jjjjjjBH|NTZ<<jj`fvvvv||lrx~ ***00< < jjjjjjjjjjjjj <<<&,2p8>v|DJPV\b6hntz0<0jBT    jj   "j ( .< 4 : @ F Fjv L R X ^pj d j< p v | | | **J J >$ 6          4    | $ *J 0 6 <$  | B H N T Z ` f l r x*0 ~   @    p   HZ|     &   , , 2  8 > D J P V P V \ b h n t r  z z  * ** 0 , 6 < 0<  | .& /,2x` fDX2HH(H\sxHAHHpppph7pp8HHPbppppp pHHXHJHlN6 H ):X_HH}H`DHp! xxHJ3D|0DpDpp X:pph@|phpl\Hp^& 6@EGIKMQSZ ]]4:6<BHNTZ`flr6x~BVV>V-VnxlpVnVVV=VXV'VV-VV p`bss!#%% )+!/1$66'::(BN)HI6KQ8SS?`bss!#%% )+!/1$66'::(BN)HI6KQ8SS?@             &&,22288>@BBHNTZZ`flrx~~~~xr~xP O80t`t`TLh@!,Xhh<,(,,(dthFhF@<<<0x(F(dP<d(@,< djdd  $$&(,- 25"89&JJ(RR)TT*dd  $$&(,- 25"89&JJ(RR)TT*+    $*06<0 6000BHN6*00HTZ666666* + $*00~t`VV4\4\H 6fl$$*D)`dos""PEKNO<-2"FEKNOFtsdtdpqtod    xzz    dPP    J   H:TfTx:::TTv       J::::::TTTTTTTTTT : : :  T T T T T:   :  v v HHH :  $$$Bl l $n%8 %J%h ff%f%f &&X&^ &h&n&' &'P&h &h((&X&&n)&h'P'P (( *h**%+F*h+F *+` +F**+r+r %+x*+r+r+x+F+`&* PPP+ :+,&%(,0,n+r&X&,&,.. . ( &n,0&n,0+`+`( ( (,0&X'P*,n+r( /:0<0^011 *h11&h+F&h+F&h+F'P*/:*262p3 &X&*333311'P*'P*+F3%%&h+F4F4'P*'P*'P*& & %%( ( &h+F *h5>( ( ( ( &n+`&n+`&n+`&*/:0<11&h133'P*335T56L6~'P* : : : : : : : : : : : : T T T T T T T T T T +++++,&,&,&,&,& v$ $)./ 247>DFHIKKNNPS UU$WW%Y\&^^*+78=DJNORST^_`adnostwxyz{|}~$(**,,..0022446;==??CEGGVV[_abddffhimmooqvxy{|~~      !! PQ UV]]__ggimosuuwwy0O[]^_egimnx   AFJLLNNPPRRUUWWYY[[]^cceeggiikq~//k  6 I 45Z[ij{~   ghiknoprtv{|   qrxQfms*9:<68:V_bfimsvyz{~ !lnp$C U "$&(*,.0$~~$;C}~ ~U "$&(*,.0$C U "$&(*,.0  }  p"$8=DJPQSUX *+,-./012345;=?CDF TUV^_ "#$%&'()*+,-./01^_`abcdefghijkt"$8=DJPQSUVX !*+,-./012345;=?CDFJ TUV^_ "#$%&'()*+,-./01^_`abcdefghijk= opwy}  z  ky  < YZ[\7 jy}~    m     J< FGHRTV!HJ ]3579=?AGIKOQSUWY[]=F2G2H2R2T2222222222222222222222222222H22222]22222232527292=2?2A2G2I2K2O2Q2S2U2W2Y2[2]2  y}  1 &*247$&G| \xFHJLNPRTVXZ\~  ( ( F@F`F( (O$&*247;$&CG} U\x "$&(*,.0FHJLNPRTVXZ\~5 YZ[\]7<>@ y}    mt gijkoptz{|~    t2  =F2G2H2R2T2222222222222222222222222222H2((((]2(((((32527292=2?2A2G2I2K2O2Q2S2U2W2Y2[2]2"$8=DFGHJPQRSTUVX !*+,-./012345;=?CDFHJ TUV]^_x "#$%&'()*+,-./013579=?AGIKOQSUWY[]^_`abcdefghijkfmV_bdipqrtux Q~~V_bi~ ~ V_birx Q V_bfim _&*247$&Gfmqrsux|Q\kxy}    FHJLNPRTVXZ\~  $&*247 89:<=DIJPQSUX $ & *+,-./01234568:;=?CDFGV_biy~45TUVZ[\^_iopx{ "#$%&'()*+,-./01FHJLNPRTVXZ\^_`abcdefghijklnp~ 29:<68:V_bfimsvyz{~ !Plnp y~ y~  py~ k     !~~~ ~op  oyU22222222222222222222 h2kn2opr2sv2222222222222222222 p'  jz~  7 opw}  qx   j~      < << <-Z   ( (8=J*,.024;=?( (^^`bdfhj   p22  j~  pI]<>@ 45Z[hiknoprtv{    p op@  oy}    }  %  y}    )  y} t  t  ( ("( (   j~  }  )  jy}~    *  y}    V_bi  o}  j~  +  oy}   y~0 &*-247$&G \xFHJLNPRTVXZ\~  fmqrsux Q-< Lcyrlgrek"latn0aalt2ccmp8ccmpBccmpLligaVrtlm\rtlmbrtlmh 0@P`ph< T"*2:BJRZbjpx&.6<DLT\djrz^fnv~ (0 $*2:BJRX`hpx$,4<DLRZbj                           LMW`bss!#%% )+!/1$66'::(BN)HI6KQ8SS? (B~FPZdnx  (2<FP ` a ` a ` a !` "a #` $a %` &a '` (a )` *a 3` 4a 5` 6a +` ,a -` .a /` 0a 1` 2a 7` 8a 9` :a Y G k l m j n o '*,./0I 4L5OZIL[IO  ; < = > V 7LMWlinphone-desktop-4.2.5/linphone-app/assets/fonts/NotoSans-hinted/NotoSansUI-Regular.ttf000066400000000000000000011253401376717241300312100ustar00rootroot00000000000000GDEF4((GPOSGSUBF # `OS/2SC`cmapO'hcvt 7fpgm6  . gasp#glyfL^dhead[x6hhea OT$hmtx=x%loca"8%maxp x name۴}postif prepf5\)_< 4( b   o pRT`\K33f GOOG@X J 'D+3dmfRf=hTf%TR%db\+qZdf%%?fsfy1w3}s'}R/`1B?}?}dhsqN3N}^qqqqF{qqNh!J;%P 9h Bf'Byhy1dBRfRdm{f1#=q%LBPRGR.R y3 }ssss<R<=?}?}?}?}?}?} }^}^}^}^}^}^^qqqqqqqqqqqfq}^}^}^}q}q}q}qq=qsqsqsqsqsq}q}q}q}q,R3RR/`FF11\111?}q?}q?}qm}oNNbN~dhhdhhdhhdhhs!s!s!qJNPNPNP}^ ^?}qdhh+m#%31)sN?{RBqH?}JsohomBN<qXq % oXqqFV`oqFqqqhBsqBss1%}dhR</`}31 sN%%B?}}sohLT#=j-}^uw'qD%%;qq)o;%/?%9;y!qwqh;B}qJqJqJRRRJff?fT{T jdD{R{P y-m\D5/)o)/#BNfRER#RGRfb) Hfd%w `fffjo{=93Vy%TTf B{}^ zsF}q=dM1s%q%'f`wo= =omB}q!! }q}Fq{o'%{qhu))HF/=/y5D;^ND\uR/F% B;}#q}qs) j%)7R-7R-R{ LV R}^}^ ^sqyhyhNDH%%%%?}qB}qB}q=;=w9=/yf%;%q71o=HyNHLNV}#q?)mX}^}^}^}%}^}^}^}^}^}^}^}^sqsqsqsqsN?sqsqsqR{R?}q?}q?}q?}T?}q?}q?}qF}qF}qF}qF}qF}q=d=d=d=d=dqjjfqqqf-s!?}q={hqos{yo'}yFFV=B}}q{d`\Jy!!sBLVNPHqF9bHDJ!!!' V q`B!D%}^?}qh}^}^ ^}q}qF?}q?}qH V q}qJ}^}^sqsq1?}q?}qN#NNq^wqNP}^sq?}q?}q?}q?}q qq}q1shP}3sq/`#}qN}qD?bqqhhhXD3DqoqqJ B{{{qqBsoNNNNN%yyh-!=JPVPhh5hq?}\q=F{qhh5qqBq!!!L11'sfff5+5+PP!H3H3H'H++!!5+5+oBj+DXXXXXXXJhh%}}}})))V dfdf33LL-))) ~9Y}5Yj5}/}W~BW BF%T=TT'w=TTBBTTT )))DqD%?fo3}q}qqFsb+f={dsq5^d`31)T!}qs)3qqB}q;}B?}??}qqJ7hJ-yJV3+y-H33jhuyy7171+NLNN)VDd !5m?hqqodqy;TDbqmq'h%yZyh'bh}h}bXHfRhFhh\1X-;fbhh-;bhhqq{NF%V! q=oFR{NRhd;%P}^qqqXD1hDDhNZhHD/f'H!N!Nhbfb\1'D-RR^R-h}BBZT333}qqqqqqsqsqsqsqsq'}qZ>)FFF1111B{B{?}q?}q?}q?}qNNNNdhhdhhdhhdhhdhhs!s!s!s!qJqJ;%;%NPNPNP!J}^qqqqqqqqXXXXXX%VL##8qqqqqqBsBsBsBsBsBsBsBsqqXXDqqBsBsqqqqqqqq d X   w w BsBsBsBsBsBsBsBs {      w wqqqqqqq!?h,+hBsBsBsBsBs N!LRh N%')#yZ}hhL'}bJds{\'1}d}"d =R.R1-F y%dj#f{mmb))s+jVFR?;?;fBhf11}^!  7yNP#}%oDq!'''%f'' +VVVVVNVRVNVNVFFV5V5VPV-VH-V%V%V%V'V/%VVV5V5V/)VPVLVLVLV^LVVVVVPVLVFVLVLLV/V9V?V?V??V5V5V5V5V55VLVLVLVLVLhVLVFVLVLVLLVVVVVVVVVXVVVV\V7V7V7V7V77VHVFVFVFVFFVVV9V9V99VVVVVLVVVVVLVLVLVLVPPV/V5V5VV)V/V'V%V%V%%VHV-VPV5V5-VFVNVNVRVNFVVVVqqqqqqqq 3j3j3j3jd3^3^3j3j3^3^3^3^ysD- !;%#)u`f# \`` ~ac67"#ou~  OP\_'=?EMWY[]}  " & / 0 4 : < > D ^ p y  !!!!"!&!.!N!T!^!!!"""""""")"+"H"a"e###!%%% %%%%%$%,%4%<%l%%%%%%%%%%%%%%%&<&@&B&`&c&f&k&o),m,w.!# bd78#$tz PQ]`>@ HPY[]_  & * 0 2 9 < > D ^ j t  !!!!"!&!.!M!S![!!!"""""""")"+"H"`"d### %%% %%%%%$%,%4%<%P%%%%%%%%%%%%%%%&:&@&B&`&c&e&j&o),`,q. ^IvedAeY @SQzKIzx?wZI we%" {ob`aa` kLP>:6&$&8F0(.@@<"$ IJ$%KLM`abVPQWXYRh X Y Z [ \ ]STUV     ;<=>r i,-03PQ45Z[@G[ZYXUTSRQPONMLKJIHGFEDCBA@?>=<;:9876510/.-,('&%$#"! , `E% Fa#E#aH-, EhD-,E#F` a F`&#HH-,E#F#a ` &a a&#HH-,E#F`@a f`&#HH-,E#F#a@` &a@a&#HH-, <<-, E# D# ZQX# D#Y QX# MD#Y &QX# D#Y!!-, EhD ` EFvhE`D-, C#Ce -, C#C -,(#p(>(#p(E: -, E%EadPQXED!!Y-,I#D-, EC`D-,CCe -, i@a ,b`+ d#da\XaY-,E+)#D)z-,Ee,#DE+#D-,KRXED!!Y-,KQXED!!Y-,%# `#-,%# a#-,%-,CRX!!!!!F#F`F# F`ab# # pE` PXaFY`h:Y-, E%FRKQ[X%F ha%%?#!8!Y-, E%FPX%F ha%%?#!8!Y-,CC -, %EPX ED!!EDY-,!QX d#d b@/+Y`-,!QX d#dUb/+Y`-, d#d@b`#!-,KSX%Id#Ei@ab aj#D#!# 9/Y-,KSX %Idi &%Id#ab aj#D&#D#D& 9# 9//Y-,E#E`#E`#E`#vhb -,H+-, ETX@D E@aD!!Y-,E0/E#Ea``iD-,KQX/#p#B!!Y-,KQX %EiSXD!!Y!!Y-,EC`c`iD-,/ED-,E# E`D-,E#E`D-,K#QX34 34YDD-,CX&EXdf`d `f X!@YaY#XeY)#D#)!!!!!Y-,CTXKS#KQZX8!!Y!!!!Y-,CX%Ed `f X!@Ya#XeY)#D%% XY%% F%#B<%%%% F%`#B< XY%%)) EeD%%)%% XY%%CH%%%%`CH!Y!!!!!!!-,% F%#B%%EH!!!!-,% %%CH!!!-,E# E P X#e#Y#h @PX!@Y#XeY`D-,KS#KQZX E`D!!Y-,KTX E`D!!Y-,KS#KQZX8!!Y-,!KTX8!!Y-,CTXF+!!!!Y-,CTXG+!!!Y-, T#T[XCPCT[X!!!!H+YCPCT[XH+!!!!YY-, T#T[XCPCT[X!!!I+YCPCT[XI+!!!YY-, #KSKQZX#8!!Y-,%%Ij SX@`8!!Y-,%%Ij QX@a8!!Y-, #Id#SX<!Y-,KRX}zY-,KKTB-,B#Q@SZXB TXC`BY$QX @TXC`B$TX C`BKKRXC`BY@TXC`BY@cTXC`BY@cTXC`BY&QX@cTX@C`BY@cTXC`BYYYYYYCTXBY-,Eh#KQX# E d@PX|Yh`YD-,%%#>#> #eB #B#?#? #eB#B-,CPCT[X!# Y-,Y+-,-@ !3 U     U3U?[PZU?ZOZZXUYPXU0X@XPXXWPVU VVVTUUPTUpTT0T@TTTT0MMNUGdFU?FFFKUJPIUIKUOPNU3NNKULPKUKK?KKSPRU;RRPUQPPU7$~adX}wsvsAus2ts2sss3U3Umili&ki=jiHiZ&&H&H&&&###3@mUU3U?d]4xcb]#a]3`]*_]*^]3]]]]dU3U3UOUdUoTS++KRK P[%S@QZUZ[XYBK2SX`YKdSX@YKSXBYss++^stu+++st+++++s+st+++ssttt+++++++stu++++s+s++s+st++s++++s++sstt++st+s++s+st++ssst+^ PuHjJ3  ` @5 }jHHHHnP8z0  v  "  <`pB:N*|(bX H(n* !!"d"#$$$%%%&b&'X(())*B*++,,,--./ / /|0*012x234D5B56h6678,899:B:;;r;<">??>?n?@xA6A\AAABBLBzBBCCD D8DhDDE<F"FRFFFGGHtHHHI I2IZJJJJKK@KhKKKLLMM<MbMMNLO OFOjOOOPPPQQ@QfQQQRR4RXRRRRS.STSdTXTTTUU4UZUUUUV(VLVzVVVWW>WnWXVY"YPYvYYZZ(ZNZrZZZ[[L[|[[\>\l\\\]]6]\]^^h^^^__6_Z_```aa8a^aabcccddDdtdddee@eheeeff,fZf~ggghhFhjhhhi iRixiiijjJjnjjjk"kJkxkklmoo>odoooppbppq^qr*rrsrstXttttu$uPuuuuuv6vFvVvfvvwBwRwbwwwxVxfxxy>yNy^z@zPz{{||(|L|p||}~^~nbl|NxrN"Fl<j 0brJ JZ Htb6HX 6\(~HX*Z@r$:<L*h4Z <d*RF R| D"r N|NN ĂlvT|ǢPȔ*ɬPʖnnnnnnnnnnnnnn2 "КhіѼ "ҢVӔԊRְ֞<vצ"ټچX2ނN4. *p(NZ\$tlP"B2Z*lBh"  " H       " *.TdVlTP` 0`2Bv * R !!!" "F"x""""##L#v##$$*$\$$$%2%%%&&'h(()n))*+,v-:-./V/01r223>3445H56 646h6667(7R77899F9|99::<:v:;<<>>4>j>??@>@r@@@A AHApAABB*B`BBBD4D\DDEE&EVE|EEFF(FPFxFFFG(GVGzGGHH*HXH|HHHIILIrIIIJRJKTLLMbMNOfOPP&PNQ>R>RNSST8TUtVV$VWfXXYlY|ZNZ[\l]]t^^_F_`aDaaabcd2eefVfgghrhiijk,kl@lmn.nojp>qqr2rszsstftvttu&uLutuuuvv@vfvvvww>wbwwxx,xlxxyyyz zHzrzz{||}}F}v}}~ ~@~p~~~ 8\ ,V 8^Fp"Rx*:*Xn F| 8`xH2 |lv(86dH,~NBRbj@Ph\l t(FT\lX&D<.j```8@(ÆÜĊŤfv>Ǹn0̀rVИьJӚԶrnR׬:Pf,Br۠ 2b܈ܚܬ&8J\n݀ݢެh<rBx*Zj*hT0Z,>P*f8f0pHTzBTfxFx0Vz@h L p$^pl8L~P$^|R|>lFB*P^p 6hxV 2  n 6   b2r tF:d"2BRbrj*:l&6Fvd < !!">"#0#$$%%&&'(()H)*Z*+6+,--.,.//0R01&1p112\23<345V56*67778@889d9:.:;N;>?P@X@AzBBC`DDE.EFBFG2GGH HI*IJJJKzL$LM>MNNOFObO~OOPFPdPQnRSTVW XHY0ZZ[\]^4_`2`a*b$bcdefPgXhhriVjjkl`mmnPnopqr|stzujv vwHwxyDyz{`{p{|b|r|}}~:~<v,PBLH z(z@P P4L|*b*Rz8t`> N,T<z<fJfJx Fl>zJ&Tz*Rx4jBj>l V J FLp6\ :b6lBp0V~@h(\ 2X~ P Fl.TP"Hp:j6j 2Z,`$Lt8h 2X"JxDx>d Fj:t X JÐdĴ:pŦLƂƸ<ǂTȢ(dɠVʔXˠ0v@f͞ XΆξBϰ(8"X~Ѳ :jҚrԨHn՘.^b:`؊ش(RـٸHۈ6pܖ.^݊ݲlގ `ߊߤ,V&&>NBz\b:X 8XB6Jp:^BL\lzH8p(hDPz:b P  H  ,     L t<j&(!""Z"""#*#Z##$6&&','(:)d*N+`,&--.z./2/0X1<123B446667889 9:<:;^< <=B=>V>??~?@ @P@@ATAAB(BZBCCBCpDDDEEJEFFpFGG^GGHFHHI(IxIJJlJJKFKKL@LLM"MxMN$NfNNODOOP<P~PQQrQR R`RRSDSST.TTUUfUV V`VVW<WWX.XXYYVYYZPZZ[2[[\$\r\]]l]]^F^^_F__``h`aabaab@bbc6c~cddddeeLeef>ffg,ggh hbhhiPiij8jjk(k|kllVllmLmmn.n~noofoopHppqqDqpqqqr rLrvrrrssHsrssst tLtxtttu(uTuuuvv6vdvwxLyyzn{{|4|}:~~*vBHf:JV.,:&  "8Nd @  /2/3993310!!7!!IhyJh9@  P`  }Y ??+9/_^]]993310#34632#"&Nu3A>>AC<=BBGI@@LJ@  ?32993310#!#H)q)9(q)3{@C    !?O   ?3?39/333339/]33333933333333333310!!#!#!5!!5!3!3!!!?TTPNA+RR'RR%@}TTHNNH &-s@? '% *!!./$**%  vY +vY@//]]33+3/_^]33+393339333333310#5.'5.546753&'4&'6˼rDKcͪʭ8J^sVj^b##3AG= Z6`{dHU( IZ&uZdB  ,0G@% '!-'/12* * * $0/$?3?3??99//33933331032#"#"&546323265#"#"&54632 #GNNGɝGNQMNGɞ՝+LJڧH"Jm 3^@5%"+&,)&. 45%.+1& ((- lY1 iY1?+?+?9/9999993333310>54&#"27%467.54632673#'#"&GP|ffQYiVaMA$Ƴ]3E+rAOE~QL\^S\qhWek;m\lݬfZH?9310#H)q)R) @   $??99331073#&R1 ή26= @  $??993310#654'31:1T{E@*      ?  /?]9/]39933310% '%7)󰮞+wo`f`Dof) 4@  /_/]333933310!!#!5!3hhZT@/?/]9910%#67{7yA%RBu(@/_/]]]399105!Rՠ @  }Y ?+991074632#"&A<=DD=;BoBGGBAKJ??9910 #!Jd/ (@  sY sY?+?+993310#"3232#"/ꑞr~r!74" $@    ??9/9993310!#47'3װ fy^tUcy3b)4@ sYuY?+9?+933310)5>54&#"'632!)9p7xZe`FQt32򝒯t[]crg}akZZ`"-.2!iv5F{GQ+j @@   uY ??9/33+3993333310##!533!47#jԯD} 7JLL0̉h=@sYuY sY?+?+9/+993333102!"'53265!"'!!63JcvZ7#sO,4(9Xq3$R@, !!%&  vY  _  vYsY?+?+9/_^]+999333310!2&#"3632#"&2654&#"qtALe nזzWWPqZ̬%ڲHDddZ/'@uY?+9?9310!!5!Xd-"/L@'-&&- -01 ** #vY vY ?+?+93999333333102#"$54%.54632654&'">54&H/xn2v6fps˺nKVz̽Nqtw`C>]pc?`L/9Ydof)%P@+"  &' vYPsYvY?+?+9/_^]+999333310!"'532>7##"&5432"32>54.)`tDMgo pՖyZTOFЪ &I|Edef (@ }Y }Y ?+?+99331074632#"&4632#"&A<=DD=;B?>?BD=;BoBGGBAKJBIHC@KJ?f/@   }Y ?+/_^]910%#674632#"&h4|A ?>D=;Bh2\BIBIJf+(@0p/_/]3/]/]10%5 +;fs6@  O//]3]]]29933105!5!sVThf+*@0p/_/]3/]/]10 5f;BnfXD'D@&"()P` %%}Y% ~Y?+?+9/_^]]933105467>54&#"'632432#"&L`mDxP_?վ(QycA:CD98G7wP\PP5cj(.eJrfeUo["ӉEDCIBwJ6@K@%*$/7<</AB3>399 , 3',%?3?39/3339/39933333310#"&'##"&54>3232654$#"!27# $!232&#"YiUt 'dkȀECYn>/lQ INیcOS_˲u,ҭXTd߶5 ,@   iY ?3?9/+99210!!#3 '\;:ZF!;DhxcE!b@5 "#kY:kYkY?+?+9/_^]_]]+9933333310! #!!2654&+!2654&#&' Hnxj}}&@ iY iY ?+?+9310"327# 4$32&9]p?J):"hTVPZ(@   kYkY?+?+993310)! !#3 ZuiU|R U@1   iY: iY iY?+?+9/_^]^]]]+933310)!!!!!1Ty8 F@+  iYI?_o iY?+?9/_^]]+93310!#!!!!1R};=@ iY iY iY?+?+9/+933310!# 4$32&# !27!BtWF 3%&cVVT#% E@'  iY8i0 ?3?39/]q]]q+99333310!#!#3!3%VjRb 9@   nY nY?+3?+393333310)57'5!bj')jj)n'`{u @  iY"?+?93210"'532653^:GMdd{yra 8@     ?3?393993333310!##373~ /F@iY?+?9931033!Ǹ{0@   ?33?3999333310!##!3!#47#LRJN,@ ?3?39999333310!###33&53N - QGs'B9} (@  iY iY?+?+993310! ! 32#"_G>b|nheq,&%)o 2@  kYkY?+?9/+9933310!##! 32654&+o꨸%Ķ!}@@!    iY iY?+3?+_^]933310! ! 32#"^3_G>b|FJheq,&%)A@    kY   iY ?+?39/+399333331032654&+#! #۲ѸEeq\h%:@  &' iY iY?+?+999333310# '532654.'.54$32&#"]`<ˮ۸99LE(.~nI^R4JɟRNpeH_N232%26=T#R|lwWD7S` igINA}w4 ,2}cjrV\{!<@  "#  ]Y]Y?+?+??9999333102#"&'##336"32654&o7 oǦ\POxqqq^(@  aYaY?+?+993310"32&#"327f P37br#+!4@;q= @@!  !" ]Y]Y?+?+??999333310"323.53#'#'26=4&#"3w  sƤ( .y쓧!q^K@(    ^Y]YaY?+?+9/_^]_]+99333310"32!3267"!.Xj[/+9m-' ߦ;@  ]Y ^Y?3+3?+?9333310!##5754632&#"!il0]F[XBT>?%xGq=^ (I@&" (()*]Y]Y %]Y ?+?+?+?9993333310%26=4&#"7##"32373#"'53265Poy +u) 2FVL4@     ]Y?+?3?999333310!4&#"#33>32w 1q8Z@PZ5s)@  cY???]]+9310!#34632#"&b=-*??*-=J)<66<;88s 6@ cY`  ]Y?+?_^]]+93210"'5326534632#"&-^@ECNI%=-*??*-=UW_<66<;8838@     ?3??939333310?3 ##3`=F_D}5NTs+mmӲb@ ??9310!#3b^"B@!"#$  ]Y?3+3?33?999333310!#"#4&#"#33>3 3>32#ߙmt /jN 5tÂJPZX`5L^2@      ]Y?+?3?99933310!4&#"#33>32w 3oJQY5qh^ (@  ]Y ]Y?+?+993310#"&53232654&# h| ã'ҋ +{^!@@! "#  ]Y]Y?+?+??999933310"'##33>32"32654&w @n)N==6ZP۸#q=^ >@  ! ]Y ]Y ?+?+??999933310%26754&#""32373#47#Rou s%Օ,  /n</^,@   bY?+??99933102&#"#33>I8=:WT?^ `gJmphy^#:@  $% ^Y^Y?+?+999333310#"'532654&'.54632&#"yـ|w~;=ptd>/EXXJAZ:73`E D_Jy` !'3J"@  !  ?3?3399910!&'##3376733673/2* Ӻhm Ľ  @jMbJkZW>Zk#OMILJ%J .@      ?3?399933310 3 3 # #1bJJ,@  ]Y?+?3?999331033>73#"'5326?K @'EKJ2FVx&9J_%=o _cPsJ 8@ dYdY?+9?+993310)5!5!!sNTwG9^@8  x//$?3?39/]q]]]]]39933333310>5463.54 v׿tpslvn΁y]`/^_' |jdX-hY@ ??93103#閖B\@7  x//$?3?39/]q]]]]]39933333310#565475&54&'53zvmπzVgϚ)' '+dYiXfL+X*@@H ?o/]33+229910"56323267#"&'.P56dFwQI^.66fH~HI^C6l"@9n! ^8@ _o   }Y ?+/9/_^]]9933103##"&54632w3A>>AD;;DHCFEDBIHU@"  tY tY p  @ H    ??99//+]3+3+93333310%#5&5%53&#"3267qv5eY?9>55#BHZ@0   wY sYuY?+?+9/_^]3+39933333102&#"!!!!56=#5346@uz_AKTNy`-/׈/y'[@1   ""() P%/]3]29933333333333331047'76327'#"''7&732654&#"HddyhcHH`gzbbHooonulaGGaotc`EG`lwoprsq@C     wYo wY  ??39/]3+3/_^]]q3+3933333310 33!!!#!5!5!533Hnd5˰6i(@ ??9/9/9333103#3#閖y.:U@- 5/"/)55);<8,383 lY  &mY ?+?+93393333333310467.54632.#"#"'532654&'.7654&'VLJR\k7aJsmt҈WMjŏ6yAR)W$(pT{*';=8T7Cl\PC'-JG=O=I3KF>LoQm:c1 q 0@   0  /]q]3339933104632#"&%4632#"&18('::'(88&'::'&8s5//552255//5522dD&6L@.'// 78p    #3+#?3?39/]39/]3933310"327#"&54632&4$32#"$732$54$#"}wu_x}6^ZƬ֭+*Bw!=@  "# @?3]29/399333310'#"&546?54&#"&'632%32=^aqsNDdjzNnbobVcdggj-=<5>&b/9Rs 3@     0/]q3/39333310 % RX])JKJKf)*@/_/]33/99310#!5)RBudD&6i@= ' //78p#3+#?3?399//]3]39/q3933333331032654&+###!24$32#"$732$54$#"fQYRZdVJ^^m+*լ֭PAIASysb^ZƬ֭+*.@+;k{/_]]q33310!5! {V @  ?329933104632#"&732654&#"{{sOQnnQPrOqrNPqpf) D@(     /_/]q333/393333310!!#!5!35!hh!Z71Ju,@   ?39?399333310!57>54&#"'632!sGK>>d5H4SJn{qEAB0(^qo.OQ\#9!K@+  "# _ !?3?39/]]qq399333310#"'53254+532654&#"'>32wtuug_MBh{JJQ9,:FqNA;BN^7.y! "@  o  _  /]]]9910>73#&u(,?w0N@1NJ9@     ]Y ?+???39999333331032653#'##"'##3b mݒZ <\J6qd'@ ?3/39/93310####"&563!dvw>T1Z3H^ @  }Y /+99104632#"&A<>CD=;BAJK@@KJ1@   @ H/?39/+399333310#"'532654'73A%$HKMXw5cl p '3Ym&LJ @   ?2?9/9933103#47'V.G5Cs&]dB '@ @ ?3]2993310#"&5463232654&#"íXfdZZddZmywwyyttPs 3@     0  /]q3/39333310 ' 7' 7]hZeK_^JdeK_^JdG'&{;) ?55.'L&{t^?5 -'';su ?553w`^%W@7  &'_o ##}Y# ~YO_O/]q+?+9/_^]]93310327#"&54>7>=#"&54632ZJdFw?(Rxg=>?I46I5uTonT`mXbIqfgZoX!/GBIBBs&$CR@ %&+5+5s&$vR@ N%&+5+5s&$K'R@ %&+5+53&$R R@ #%&+5+5)&$j9R@  %#&+55+55$V@-    %&  o "iY " ?3?9/+_^]23399333333210#!#.54632'4&#"326m<3554&# #4632-OA@udŸn@DQpviDHJAp>I"(BL\dE(.GhGK}W?i57\3NVT^!&DC*&%+5^!&Dv1 +/*%+5^!&DK3-%+5^&DR/;%+5^&Dj&8%+55^&DP,&%+55^^(3:y@A )/88/;<#& 0`Y77dY7777& 4 ^Y !aY!&&,^Y&?+3+?3+39/_^]_]++99933333310%754&#"'>32>32!!267# '#"&7326="!4&^qt8Gg+6pB5X^Xf}RƈhVw }1NEzvT(6S]U]o!+' |k\Vcj*q^&FzL 1 %+5q!&HC!% %+5q!&HvP [%! %+5q!&HK )# %+5q&Hj . %+55p!&CQ %+5C!&v$ m %+5c!&K  %+5*&j %+55qh'l@< ""()     ^Y %]Y?+?339/+9/9_^]99333333310#"54327&''7&'774&#"326h^ ;MVbIfN˗3wֱp:3{IKnuu菦L&QR  * %+5qh!&RC!%+5qh!&RvZ >!%+5qh!&RK %%+5qh&RR !-%+5qh&Rj*%+55f+ Q@7  0 @ p  ?/_/]33/]32/]q3933105!432#"&432#"&fspB.0CspB.0C{{B;;{{B;;qh"T@/  #$  ]Y  ]Y?+?+99933333310#"''7&327&# 4'326hqRv\ uPy]1Il/=El'CsP +JsN`r4`d/D!&XC %+5D!&Xvu S %+5D!&XK" %+5D&Xj!' %+55!&\v ]! %+5{!A@" "# ]Y ]Y ?+?+??999933310>32#"'##3%"3 4&dCjx >%[Mҟ(56FN'&\j* %+55&$MBR@%&+]5+5^j&DM)(%+5>&$N/R@ %&+5+5^&DN)1%+5=&$Q%+5^=\&DQ 23%+5}s&&vR@ !&!%+5+5q!&FvH   %+5}s&&KR@ %&v%%+5+5q!&FK I$ %+5}7&&OR@ !&u%+5+5q&FON U %+5}s&&LR@ "&v$%+5+5q!&FL Q# %+5Zs&'LXR&%+5+5q&G8 \!!%+5=Zq(|@H&& )*_Y#]Y  ]Y?+?_^]+??9/_^]^]3+399933333310"323.=!5!533##'#'26=4&#"3w  Ls£& *n(})#&(MR@& %+5+]5qj&HM  %+5>&(N R@  &  %+5+5q&HN ' %+5&(Of5@ &  %+5+5q&HOR " %+5=&(Qm %+5qZ^&HQb&!%+5s&(L R@ &  %+5+5q!&HL (# %+5};s&*KR@ )&z)#%+5+5q=!&JK 60%+5};>&*NR@ &y'%+5+5q=&JN ,4%+5};7&*OXR@ %&"%+5+5q=&JOZ  )/%+5};;&*9% ;%!%+5q=!&J: -.2%+5%s&+KR& %+5+5L&KK!@ $&$ %+5+5m@<   lY` iY0 ?3?39/]q+9/_^]33+3393333333321053!533##!##55!ǸǸmV/Ls@A      _Y    ]Y   ?3?9/]]+9/_^]^]3+399933333310!4&#"##5353!!3>32wN 5lՇX@UU^3&,RR@  &! %+5+5&R  %+5,&,MR@& %+5+]5<j&M %+5>&,NR@  & %+5+5G&N %+5R=b&,Q  %+53=&LQ  %+5Rb7&,OPR@ &  %+5+5bJ@ ??9310!#3bJR{+&,- % %+5&LM +%+55`{us&-KR@  %&+5+5]!&7K@  %&+5+5;&.9%+5;3&N91 %+53J5@   ?3?39393333103 ##379a TJoJ㋉fs&/vnR@  %&+5+5A&Ov"@ k % &+5+5;&/93ô %+5\;b&O9 %+5&/8%@   %+5?5&O8; %+5&/Oi S %+5&OOL8 %+5 H@(     @ iY?+?9/_^]993333103'73%!eGI9zgX># 3@     ??9/9933323107#'73TLϴiIf[yDHBys"Ns&1vR@ &N %+5+5L!&Qv} Q %+5;N&19 %+5;L^&Q9Xʹ %+5Ns&1LR@ &  %+5+5L!&QL# ! %+5'Qv %+5{N;@  iY"?+?3?3999333310"'53267##33&53b:GUfm {unmVN^<@ ]Y]Y?+?+??9933310"'53254&#"#33>32'V;<>w} 4nȏkJRX}&2MR@&%+5+]5qhj&RM%+5}>&2NR&#%+5+5qh&RN #%+5}s&2SR@ +&G!'%+55+55qh!&RS\ >!'%+55}n@@  !iY:  iY iY  iY iY?+?+?+?+9/_^]^]]]+9333310)# !2!!!!!"327&f`YAjZ%L5uVUig8#\!o'\*1m@;%//%23 .^Y.... +( (]Y aY"]Y?3++?3+39/_^]_]+99933333310 '#"32>32!!26732654&#"%"!4&ހ?ш><~'DZh],={ qr4 +romtm-(;՟s&5v{R& %+5+5/!&Uv D %+5;&59 %+5b;/^&U9  %+5s&5LR &" %+5+5~2!&ULz %+5hs&6vNR@ q/+%/&+5+5hy!&Vv [-)%+5hs&6KR@ 3-%3&+5+5hy!&VK 1+%+5h&6z+ܴ,&%+5hy^&VzԴ*$%+5hs&6LR@ 2-%0&+5+5hy!&VL 0+%+5;\&79 %+5!;F&W9  %+5\s&7LR@ &%+5+5!&W8s  %+5\G@&   kY  iY?+3?9/_^]3+3933310!5!!!!#!59H70и1ᤤf!Fd@5   _Y `    dY]Y?+?+333/9/_^]3+39333333310%27# 5#535#5?3!!!!!U@k9ċHk=+U ^VHjk3&8RsR@ &'%+5+5D&XR * %+5&8MR@&%+5+]5Dj&XM  %+5>&8NR&%+5+5D&XN  %+5&8PR @ H&%+55++55D&XP'  %+55s&8SR@ %&H!%+55+55D!&XSq L$ %+55=&8Q# %+5=iJ&XQ!" %+5Vs&:KVR&&& %+5+53!&ZK -' %+5s&<KR@ &%+5+5!&\K % %+5)&<jR@ & %+55+55NDs&=vBR@ I%&+5+5Ps!&]v U%+5ND7&=O=R@ %&+5+5Ps&]O %+5NDs&=LR@ %&+5+5Ps!&]L%+5 !@  ]Y?+?93310"#!2&^Wkdh/Zuvb'D@$   ! dY ]Y]Y?+?+9/3+3933310"'53265#5754632&#"!!JICF;\Lע]u-f9^N`sT>+!dy>".y@G0 ) ## /0!@ H!!&` ,iY ,@,P,, @ H ?3/+]9]39/+9/_^]39/+9333332310#!#&54632&'>73#4&#"326q6-dxgg/(9_?y@31A;73@A^!w6bwx6=kh\C'**7;;76=;^%1=G@W&28,## ,2>CIHBBB@ HB@>P>>5;//////)) ) ) `Y ^Y^Y?+?+?9/+9_^]]q32]+]933333310!'##"&5%754&#"'>32%26=#"&546324&#"3265>7!T#R|lwWD7S` i}fgyxhe~qA12A;83?.j gINA}w4 ,2}cjrV\7evvcavva6==66==]*x iDs&vTR&]%+5+5^!&v lD@%+5}s&vR@ -&L-) %+5+5qh!&vX <,( %+5h;&69Ӵ/+%+5h;y^&V9޴-)%+5! *@  o  _  /]]33/]99910>73#&'#}g4ZX{+e58! *@   o  _  /]]3/]2999103673#&'{ri~a3<!Js~?`f+j @/_/]29910!!+`j ,@  /_/]]22/]39910"&'332673X nTsebq يG;?Cs $@   0  /]q]399104632#"&=-*??*-=s<66<;88m/ 0@     _/]]3q/2993310#"&546324&#"326/}fgxxge~qA12A;83?evudbuva6==66==#=u @   //]3993310327#"54731+,7E:ӠFF.. swBm0@   `/]]r22]229910".#"#>3232673+ROI"12h ta-UNH 01g t%+%;73#%>73##h'!Bgi/j!Bf.P87A887q @    _  /]]9910>73#5 i8lKI?X =@"     0/]q]3339/93310673#'432#"&%432#"&8$q=V_&88&)6^%92,*4;Kd/55225d/5-:2&$T%+5?5H^yu&(}T%+5?5'+T%+5?5P',T%+5?5&2DT@ =%+5?5'< T ޴%+5?58&vBT@ #9%% %+5?5&U@ #)%+555$%@iY?+?99310!#)}((ND=%+{Z@7  iYJzIo  iY iY?+?+9/_^]q]]qq+93310!!%! ! 32#"k_G=ez7Enies-%%'Rb,. @    ?3?99210 #&'#I"R Jυcd{0N1H' L@.   iY:  iY iY ?+?+9/_^]^]]]+910!!!!!5Rs!L }2%@ iY?+?3993310!#!#!%Io3J^ A@"    iY iY?+3?+39993331035 5!!' %!J-f`Nd!\7<h"+e@7' +,-"$$kY* *kYP`??9/]+339/_^]3+39333333310332+#5#"$54>;32654&+";۶D'+A˶87˴M׽Ѳ;mD@#    kYo??339/]+3393333310!##"$&53!333 3+-/!\y|NE@$    !iY  iY?3+399?+933333310"!5!&5! !!5654!ld:>bk+tX4^sG<|)&,j R@ !&  %+55+55)&<jR@ & %+55+55qq&~T 561%+5Xq&T `/+%+5Lq&T? H %+5q&T%+5y&U;@ .%+555q^ ,C@"# ))-.* ]Y ]Y& ?3+3?+?999333310%26=4&# "323673327#"&'#Rۍ{y6 )1# A"WZ< XЕ* +TT\8EfV?4 VQWP(T@,&& &!)*!""!]Y"" ]Y ]Y ?+?+?9/+99333333102#"&'#46 3 4&+532654&ȻoJGhPmXз3ǻ!$4%/-y J!@ ??393910#4733>73!<-C%A Aٻj-7["{>]0(MHuof*E@# %+," ]Y(]Y?+?+99993333310.54632.#"#"$544&'326sǩhNeWR`mլ]wªOb.@80LAEk[uҳw|I-֡X^%e@9## &'%%]YE%%%%%%% !]Y ]Y ?+?+9/_^]^]]]+993333310# 3267#"&54675.54632.#"!וʔUdqcjoWDcJ9Y]'/Kc& ]%),qq$6@  %&" ]Y?+3/.39933333310#654.'.54>7#5!1nY.Ty9T;{Re(-&#g`vG"qL^3@      ]Y?+???999333104&#"#33>32v 3oJQYIqR g@@]YIYiX  ]Y  ]Y?+?+9/_^]]]q]]]+99333310#"322!"! R  s nzl((  J@ ]Y ?+?993103267#"&5ZJT,bp6Jcb 3JV!"1@#$  ]Y ]Y?+?+?93993210#'.#"5632327#"&'&'# 7"1C1>5DC^|[8b/$%2CJZ U!P5YB! <%96 J[S~NJw J@  ??2992103363# #"J%ac[Moq0d@3(+ % %++12_Y ".( ]Y ?+/.39/_^]+993333333333104675&5467+5!#";#"#>54&'.oٌg>6}2\R{7Bw* >s/ N]piNa;#!nYJ26;"qh^RJ7@     ]Y]Y?+?+33?93310%27#"!##57!#5%1V/ߓXLNHJf^3@   ]Y]Y?+?+?99333310#"'##32%"32654&fy t%\D  Йdqq^.@   ! aY?+/.399333310#>54.'.532&#"+9{4G/qZR99lN"o\E4&-((9"4qJ 5@    ]Y ]Y?+?+399333310#"5)!3265'#"f{Tť?!>J,@]Y ^Y ?+?+39310!327#"&5!57ThF'q0ٖJuPHyJ)@   ]Y?+?39933310"&3!2654&'3u-%' Xћ|q\^"F@$   #$]Y  ]Y?3+3?+??933333310$746324&#">ыYO^܈sxeGO!*`u{#b &)rr\P 7@!"^Y ]Y?+??+999321023327#"&'#.#"56:P?-:R)QB,0A>s<ӨE4(5P-YtTkQv}lHR\ A@! ]Y ?3+3??3?933333310>54&'3#$3h$@dsȃ&  !ysJ'C@!  ()& ]Y#?2+3?39/993333310"4733265332654'3#"'#;>B;uj_fe]hz;BB7зE A( Ԏ|6ʀǝٸ&j  "%+55y&j7'%+55qhq&RT# !3 32654&+/8USmE@4=:Q8GHy!NbWul!z\b@7   iY :     kY?+??39/_^]^]]]3+3933333310)!#3!33 32654&+\sw!PbVj!zT>@    iY iY?+3?39/+9333310!2#4&#!#!5!!۸w {l#s&vR@ &%+5+5b&6FR@ &" %+5+5 0@  "iY?3+??3933310)#!3!34@۶$ W@1  iY :    iY kY?+?+9/_^]^]]]+99333310)!!3 32654&+TdTἩ8t%a Z ?@  " jY  iY?+33?+?39333310#!#36!3!!Zq%Hlh(=@!    ?33?33993333310 333 ###N//Jű<<<NF']@3#  ()kY: %%kY% kY ?+?+9/_^]_]+993333310! '532654&+532654&#"'6!2'cbןrmX`O/1{j{6G}`(@    ?3?2999933310333#47##ɬ  $ͬ U*Jh)?`b&6R@ & %+5+5 0@   ?3?3999333310!##33k<:)@ iY kY?+?+?99310!#! #"'5326!1?^J;4=O]m7 V{0%+}2no3}&\7)@   iY?+?3939310"'5326733?3%qV[fk=^-S)d?/9R+꺪Phs; 2@   "iY?+3??3933310%3#!3!3۶+@ iY ??39/+9933310!##"&5332673ϸh޸|_X5'Gvu6 1@  iY?+3?33933310)3!3!3DHJ;@   " iY?+33??33933331033!3!33#Ǹ9;! U@1  iY :    iY kY?+?+9/_^]^]]]+933310#!!5!3 32654&+!I  #z U@1 iY:  kY?+??39/_^]^]]]+9333310#!33 32654&+#3}P 粦"xV J@* iY:  kY?+?9/_^]^]]]+9933310#!3! ! 4&+ f'{=Y@5 iY:0@ iY iY ?+?+9/_^]q^]]]+933310"'632!"&'53 !5!&$ۧL9qeVc 9)NVn##_@7     iY :     iYiY?+?+??9/_^]^]]]+93333310! !#3!! 32#" ^P2XqnPV5Lr,&%)-V G@%   kY!  kY ?+?39/_^]+3993333310 #.54$)##"!3ݷq^2ΞJ^^\Du\"L@(!#$ ]Y? aY]Y?+?+9/_^]+9993331076%3>32#" !"uw荐 :m)Io#o4-/& Qaf}jG8J 1@   ]Y?+3?33933310%!3!3!3۴/ٵJNJ;@  "  ]Y ?+33?33?9333310%!33#!3!3۲FٵL{JN%#J i@@ ]YE `p ]Y ^Y?+?+9/_^]q_^]]_]_]+933310! )!5!4&#!! 7/A:y/ ZPJ i@@  ]YE `p ^Y?+??39/_^]q_^]]_]_]+9333310!2#!34&#!! #3b7 w JYSJTJ ^@9  ]YE `p^Y?+?9/_^]q_^]]_]_]+9933310! #!34&#!!26bF>|6ɤJXT\;^]@9  ]Y i 8 X o       aYaY?+?+9/_^]q]q]]+933310"'53 !5!.#"'>3 ^zPi3@L ;>g6"?^m@A     ]Y E      ]Y]Y?+?+??9/_^]_^]]_]_]+93333310#"'!#3!>3232654&#"?鴴򎝝' J7!J =@     ]Y ]Y?+?39/+39933333103#.5463!#!)!"9~η sw wPjZq&Hj . %+55N'@J%()!_Y!! ]Y!!! ! !!]Y?+??9/_^]]+9/_^]^]3+39933333310"'53254&#"##5353!!3>321P97:w}v 1sʐBׅ=[N\L!&v K %+5q^_@: ]Yi8Xo  aYaY?+?+9/_^]q]q]]+933310"32&#"!!3267{T;5u ]>x!(!4%;hy^VsL,&j %+55sMPJs@F ]YE `p^Y]Y dY ?+?+?+9/_^]q_^]]_]_]+9333103 )! #"'532!4&+326F``vCk%P}ㄉcYQ\Jq@A    ]YE   ^Y?+??39/_^]_^]]_]_]+93333331032)!#3!3 54&#J\ }J;J7ZPLs@A      _Y    ]Y   ?3?9/]]+9/_^]^]3+399933333310!4&#"##5353!!3>32wN 5lՇX@UU^#!&v? '%+5&\6 # %+5RJ 0@   "]Y ?3+?3?933310)3!3!#-<JN'@ iY?+?9933103!#fm-/P'@ dY?+?993310!#!3PBJ?Vs&:CR&" %+5+53!&ZCu%) %+5Vs&:vR@ "&I" %+5+53!&Zv! M)% %+5V)&:jdR.&+ %+55+553&Zj 2 %+55s&<CR &%+5+5!&\Ca! %+5Ru(@/_/]]]399105!R\ՠRu(@/_/]]]399105!R\ՠRu(@/_/]]]399105!R\ՠ9NK@.  `H/+3]/]3]333210!5!5!5!NRR9N ?9910'673% b8B%Z yN?9910#7?4|F ?u@/?/]9910%#7f0C$P ?9910#&'7%B-m^e@   ?32910'673!'673j.C$ f6C$j`Sr@   ?32910#7!#67=1A#;1B d4]'@  /?/]33/3910%#67!#67B0A%;0>h&h 9@    ??9/333933333310%#53%31J13__{i@8         ??99//]3339/3339333333333310%%#553%%?_21X++X12_+{$|d   /99104632#"&tonuwlnuzzz "&@ #$ }Y  ?33+3391074632#"&%432#"&%4632#"&A<=DD=;B}$?399?3??99//339993333331032#"#"&546323265#"#"&54632 # 32#"#"&54632GNNGɝGNQMNGɞ՝+GOOGɛLJڧH"JKHH Rs+$@ 0/]q/993310 RX)JKPs)$@ 0/]q/993310 ' 7)ZeK_^Jdh']!%+55y??3310 #}Jm<@"    0 `   @   ?3?]q2399333104&#"#3363 LLNoZ|f IUEe|XeP\#a@7  wYtYI?_o   uY ?+?9/_^]]+9/3+393333310!!##53!!!!6ʲ@ 'DJ!@R  "#wY   wY/?O sYuY?+9?+9/_^]q33+3/_^]3+39333333333102&#"!!!!!!56#535#535ƥ@ca?MPEq-+ )i@7 !%  %*+  _Y!kY)kY^Y?+?+?9/+9/+333/933333310%267#"&5#5?33#!##! 32654&+f%QCpv}?i5?5µT} RIՉVLR!/y&@$ '( /wY   wY/O_ /_ ""tY"tY?+?+9/_^]qr33+_^]3/_^]q]q+_^]3393333333310 !!!!327#"#53'57#5332& KL#Ǩ.((͢L+y8>,BA **N_T .M@*'",  ,/0)    % ?3?3??99//3]39333310 # #"&5463232654#"%"&54632&#"327՞+XVSYg[#SOgXiJswwsٲ%k#ko$F@!#  %&#     /3/399//3999993333310%273#"&=56746324#"6}iPpNrxεP{A>wөy&ꐟNgx!UgV'+u@A "+"( ,- %mYmY ((()lY(?+33?39/_^]+9/_^]+99933333310!###33&53#"&5463232654&#"5!^"PZZNNZYQ`mL3quuqrmm#B@$    ?33/3993333310##5!###33#7#s!T{Ǻcnn+T+/NvfH4@  ! /?/3/299//]39310"&54>32!3267.#"y1RQHbٓ2Xz#5Fi)|5BuE'd&{>j ?555#''>u ?555G'&< >} -?555f'N'>u=- ?555b9'A@"%%() !dY ]Y]Y?+?+9/+9333310#"&546327!"5>3227.#"9챰Y.:;=C#}Pcaa74QEL*(!:Vl{t~)} '@    iY?+?999331073!!&)͸'3+CqEoȂ%%@ iY?+?3993310!#!m`^H @@"    iY iY?+?+9999933105 5!! !HrH9q+r f+"@/_/]399105!f% @  //99//39310##5!3s% ^w-+J@% #)) ,-# &  @  /]]3333/3339993333310#"'#"&54632632267.#""32654&-|}y|?l41kEM_^?k51lDL`_φ԰ӮWa^ZiQQelY_^ZhPNj @  ?2?393102&#"#"'5325S.;8O==>崹l`/#/X@9(01'/$ *** ***/ /]3/]3/]q3/]33993310"56323267#"&'."56323267#"&'.N69lDvSI_/5}9iCoXK\067j?lbAa5<|3hEvOYW@9n#B9m%A7m)F3n !%f)G@,  O //]33]99/]]393310%7!5!!5!!!!!iTy3l}ߒ=f+ A@&  0p/_/3/]3/]/]933310%5 5!+;;fmf+ I@,  0p/_/3/]qr3/]/]933310 55!f;BofXj= '@   ?/999333103 # jN>N^5!4&IL '%+55#&IO %+5 &@  _/]]22/]39910"&'332673H [qgc ْhRXbbJ @  ]Y?+?93210"'532653-^@ECNIUW{ @  `  ?]9910>73#' V1bB35Ho;u @  `  /]]9910>73#o6a3bT3B?<{! "@ o_/]]]9910#5>734c2d;:8=J @@     ??9/]33399933333310##5!533!547}p}ZkCͿkd=7B@'  o !?3?39/]]3993333102#"&'532654&#"&'!!6NJ)86\mlc6K"!As{"&QYOUp 9J @ ?39?9310!5!\;]J{d39"-M@*+& &++ ./ (((((( # !?3?29/]q3999333333102#"&5467.54632654&/">54&h~JTGF=E2&1%  -, 48!59/33/33399/]]q3_]]/3/33/33/39/_qq3993333333333333333333333310!#%5!#533!5353!5!!5!5!#3#35!#35!35!#35#3#3#"&546323254#"%32+32654&+32654#"'53253T/0momImmmm0oowoooomm~smp.,=.m^{B.$*/;J1%Z^4+V}i0oo/mmmmmmoo;mmJoooo/yhIaCS1BD5QYb" "+%J fVr_cT*,@ % +,((""//99//339910 5467>54&#"63232654&#"TV,AgIOGRZ?>1HT;GFBIHCHEVW/2A1R~X8*P:/5K6DpJ;?HI>@IHc!&7L  %+5N *4g@7 2"*((+" 56+/)%**)dY**%^Y%%/]Y%^Y?+?+9/+9/+99933333310!"&547654#"'6323 4',546323%.#"jD,0'^an+`NY_F94t=ooR++wwCb;,ǑދkWH(@  kY?+??999321076>32&#" #3?E9L]@:$#-E}##۟"l2Ka/J(V@+ &   &&)* ]Y#]Y?2+3?+339/99333333310"&54!57!##"'#326=332654'7p˾EG{lt\hj[tijNH븸έ}{u&0vT@ &N %+5+5!&Pv ^,("%+5&$X; %+55^\&DX ,&%+55zG @s7 4@   o  @H @ H /++q3]2993310#"&546324&#"3267}hgxzecrB13@:93@cxudduud8;;86==f,(@ ^Y ]Y(]Y?+?+9/9+10.#"3>32#"&54!&#"32>5i%$#[7? :j瓸ɶWTpa2aQ;vk]L M]Ŭ۟'|+BJ.|.j&I'IL-,=%h=%+5+55&I'IO-,1%h1%+5+5}q ?@"!"  iY iY?+?+93?99333310! ! >5332#"aEED?h]~qjh|'+'$*q+#R@-%$%   !]Y ]Y?+?+93/_^]^]99333310#"&532>5332654&#"h| lB2; ~jEÞ'ҋ +IDCej'8@    iY ?+?39/3?99333310>53! 533265RM!ԹŴ  JľZ@2 P     ]Y?+??39/39/_^]^]q99333331032653>53#'##"&5Xw}PI  2tH?:y OVM!C!vRw-@  /_/]qq]29/310#'>54#"563 w oJX5-%L׌&m .0Rj 1} @ P  /]3104632#"&1?,+?;/0;<77<5=<s&(CR &´ %+5+5`s&CfR& %+5+5q!&HC´!% %+5u!&C %+52P@(+("+( 00(34))iY-%%iY ?3+3?3+39/993333310"'632!"&'## 32.#"3267332<_,I~tKIs|J,^<˺>|1ḅ%+Ta2222uSxT+'%=LE,!-J"+@#$  ???33939210#3367673363#&-"u6XdjKa پ}ioJlV@%acYOPKr@@ kYiY: kY?+?9/_^]^]]]+9/_^]3+3933333310!53!!3 )!32654&+:b5gӬ`5gu'z@H  ]YE `p   ]Y ^Y ?+?3+39/_^]q_^]]_]_]+93333310!!! #!#5353!2654&#Z5)J˥\YYQ%!c@: "#iY: iY iY?+?+??9/_^]^]]]3+3933310"!!327# !#3!%2.G ]q V o2ڵJi):"mQV/N^3%^!@L  "# ]Y E       aY aY?+?+??9/_^]q_^]]_]_]3+3933333310"'!#3!6$32&#"!!3267 紴 ᣄ5r Y<=J7;4%w T@.       kY8  i    ??339/q]]q+39_^]93332310!####3 !'&'ꐨbcIP: .\\JBƖd'J v@M     ]Y    M ] }   / ?    ??339/]qr_]q]_]_]q+39933310 #####!&'#Ӹlqƹc  JJ+g#Dog@9     iY8i0  ?3?39/]q]]q+299333333310####!#3!3#!'&'kal>J<AVVVjJJĘ\^1J@O     ]YM]}/? ?3?39/]qr_]q]_]_]q3+339933333310 #####!#3!#!'&`Ѷlk͸߰cs($8 :#JJ5ySY"g@< ! " #$ lY: &""jY?+99?339/_^]^]]]3+3993310#.+##"#>75 !7_sf]W BcRQa?"ć.brgKo#Mia+J)]o?śM J #@O!"##$%`Y#o-=]o   " "]Y ?+99?339/_^]q_]q]_]_]33+39333310#.+##"#>75!SlH/!7OF BO7#6NqYJi2Ni>LUDBXPb9 bi$'z@I&"!'%'"# ()!kY!iY'!:! !!!!!$#&$$&jY$?+9?39/_^]^]]]33++3933333310#.+##"#767!#3!5!N`sd.$BeV~s+'[Q#\n$oM;n](Lb?;%V㇦FJ%(@T&'#"((#$)*"`Y"]Y(""E"" """"""%  $'%%']Y%?+9?39/_^]_^]]_]_]33++39333333310#.+##"#67!#3!5!;SkH/!8QC DQ8"-%ϰ+Ji1Nh>LTDBVPt(J7`i=JBK@U( >6ABB;,;0>!E!0*LM0*..833/3 3*AkY:*H*$lY;*iY#?+?3+.39/_^]_]q+9_^]22/993333333333310327632&#"#"&5467>5!#532654&#"'67&'53>32&#"TX`xxADFBlmhź=ןmcZ3\]A70',o0Ŀ`v652'3 {j{@)D 7//7D>)GH 3443]Y4i484X4o4444 44>,&]Y&D>BB@ H>>9^Y>?++322/9/+.39/_^]q]q]]+9933333333333102&#"32632.##"&5467>54&+53 54#"'67&'53>:*+/e-z҂usMWnK{)Z+rjw7?vkVHYPu M<k8%d.<2* ){uz][`WF6R2pUmu} Y@4iYzIo  iY  iY?+?+9/_^]q]]q+99333310! ! 2!"!._G>b^ D nheqM qh^ m@C]Yo-=]o  ]Y  ]Y?+?+9/_^]q_]q]_]_]+99333310#"&532267!"!h|  -'ҋ +TFHR"@ kY?+??93310"#367>32&=N4MF!E;TnY*W8+hXBLT"@ dY ??+?93310!3367>32&#"B !6op&.).9r)5_k RVRs&}sR!&%%+55+55L!&~so& %+55}  .H@' '!.'/0.  iY iY%*]Y%?+?+?+?3?9933310! ! 32#"%33673#"'5326?ZE,'EmD N۾+ENJ7BUw*9rljs*(''GxQs \fq^&R\w "1%+5}-(Q@* & " )*" $& &jY iY?+992?+3993293333310#"'$%632>32654'#"'w|-|v .)úI6i$¹nqu+oo(95+ll,u*0&V*+((XV(q+M@( )#!! ,-&#))]Y ]Y ?33+33?33+33933333310#"&'&547>32>326'#"&' @89? >96B V <5f=46= w'&5.-8$(!$6**8&;*"J<\U>*!"+{DEW@RIMC6FM*%M; 6XYIUHU@5 HIUIU9     @9@iY'93iY-3?3+3?3+3/_^]33/^]3399//++]93333310#".#"#54632326732#"&'632!"&'# 32.#"5>54.54632Wxc*j|m:qwN#^;>YΣ&5-9D#*#tnn%-%J?@IJ'!-Z>Vb//0.vUvV>Z-ZPuJ2&'Fo *?N@JCF@F(,"F6OP HLHL@C HCLCL 2+,,55 555552:::::: :@ H: aY% aY?3+3?3+3/+_^]]q33/]3399//++9+93333310"'#"32&#"!2673 #"'>32#".#"#5463235654'&54327a/pS?x*;[Erm)9rGt}'G[;){?RWxb*56zp:pwM}ww11b9DE %' + 4d%/T4 $*$7>nk$,$QtH(:,NF &i hf>&@4 %+5+5-&j h  0$%+5{/@   iY jY ?+?+?93310"327# 4$32&HoGGK'jnXVPq^1@  aYaY?+?+?9933310&32&#"3267#sM=5dBY)*4dhu7@     ?9933333310'%7%7%{D!Ey!FC7C@ubw=E¦uu0@   @ H0 / _  /]2+993310#"&5463!>32#*05)*6,03-,6-2455+//158*8@   @ H /_/]33/+]3/3991027632#54#"+5xQmzj+dxVh;:kn!d$+$9@  /9333104632&F9/3$w9H)':$L:9@  /9333105654.54632w$4.9D:L%9')H) (6DR_m@iP4H, B&:V^&,c4k no-&44)"00)d^Wkk`ZggS`IB;PPE>LL7E)`EE`)P     ?o/]2q2/]]3q29///333q2333q2333q29333333102#.#"#62#.#"#>2#.#"#>!2#.#"#>2#.#"#>!2#.#"#>2#.#"#6!2#.#"#>]qO?#&*-O;_;;;;6@3P3333.6-&..&-6  ?/9////////]]93310#67'>737&'.'5467'67".'7&'7 F$a5; Ia4#GA݁hBO݁E?軋Ek(8PC{Lh&ZC7#BO݁GA܂ Ia5; F$a5[8D.^3DuOW.FcB=FK%b"]@3    #$ " " iY?+???399_^]22/^]39333333103333##47##"&'332673Ǭ  $ɔӞ I ]nic ەQB+lN]]1b@7      ! "_  ]Y ?+???99/_^]]33/]3?933333331033##?#%"&'332673X Lݼ} \qic J_N{hJgS]]/z@G iY iY: kY?+?9/_^]^]]]+9/_^]]3+3933333310353!!3 )#32654&+/PLmPѽ`^>{T@V     _Y]Yo-=]0o   ^Y ?+?9/_^]qqr_]q]_]_]+9/3+3933333310!!! #!#5353!2654&#b/4'!ɤ[ZYQ}Y@-    kY  kY ?+?9/+999999333333310'+#! 327'7654&+}riuib_8fqv8XVF{^(]@4 $!&&!")*!$# ]Y]Y?+?+??99933333310"'##33>32'"327'7654&w @npjDr,&wp}] =6YQT۸# Tg/ E@$   iY    iY ?+?9/_^]3+39333310!!!##53qZ}NJ G@&   dY    ]Y ?+?9/_^]3+39333310!!!##53!NX#݋L@(  iY   iY&iY?+??+9/_^]+993333310"#!!63 !"&'53 4$7^ZRf_x>XUF{w  1 JJ@'  aY]YaY?+?+?9/_^]+993333310"'53 4&#"#!!63 Njn~ N< R<  <=/J L@*    " iY?+??3?339933333310 333 3####N//°fű<<<=JK@*     " ]Y ?+?3?33?99333331033 3#### 3;gȮb%%;Ja{--5N=F&|^3- %+5D=^&| /)%+5=E@$       "iY?+???39393333310%3###373p~ /FVJ?@!    "  ]Y?+??3?993333103 3###37+wXJ_}-JP@(     ?3?39399999333333310#3733 ##}}}Z^}k+^FHJI@&     ?3?39999933333310&'#3733##N%s7N)JyJl3/X@,  iY  ?3?3939/+9999333333333103533#3 #&'##/Z݃{Ǯ^f1P@)  _Y??9/3+3?393339333333310353!!37673 ###w@,^D}\[.s+km D@#     iY?+?3?9393333310!3 ##! X+%J 6@      ]Y?+?3?993310!3 ##!%+J-Z@4    iY :      "iY?+???39/_^]^]]]+93333310%3##!#3!3%Vj Jj@>   " ]YE   ]Y ?+??39/_^]_^]]_]_]+?93333310!33##!#bTJ7N{Ju U@1   iY :      iY ?+?3?9/_^]^]]]+9333310!#!#3!!uVjJ c@;   ]YE    ]Y?+?3?9/_^]_^]]_]_]+9333310!!!#!#bTJ7ɔJJ) R@, !" iY   iY&jY?+?3?+9/_^]+93333310!#!#!63 #"&'532654&#"ݶXL1POF~+}a כ1 JR@-  aY ]YaY?+?+?39/_^]+93333310%#"'5324&#"#!#!632ÄcjoG8yM:;<=3NJ' })5m@;30$3**3!$673- ' '-kY'' '' iY iYiY?+?+/+9/_^]+999933333310327#"'# !2.# 327&54324&#">rBUN=8]fH;\1f2?2*P^ǰúdXYdZNapVd$Vy#  _RAq^ 4y@(3+%.+#%56#! .((dY(((@ H(( 0^Y ]Y!]Y?+?+/+9/+_^]+9999933333310>54#""'#"&532&#"327&54632327C:BQEH^|hvz_M'FA>i[2>B3,\/*kxfO(/ ۬~=}=&&|' P#%+5q=^&F| R" %+5\ 4@    "jY iY ?+?+3?93310!5!!3##7J7)J 4@    "]Y ]Y ?+?+3?93310!5!!3##y{<J&@  ??3/39932310#33>73bRO =RN_9@ZB@"   iY   ??399/3+393332310 3!!#!5!53D}-ӹ/9\1J<@ _Y?3+3??3993332310#!5!33673 !bTN}G8O@'    iY??39/+339/9/933333310 333673##u/}t}sGzqZ:JT@)JQ@(   ]Y  ??39/+339/9/9333333103673##5#"&5Lyp~ny Jn)TW-@   iY ?3?9/+99333103$32#4&#"#Ǹ߹|f\-vv"2;NJ-@ ]Y ?3?9/+9933310!4#"#3>32_hcl5@+JD;f7P%s@@#$$&'##iY#z#I### ## iY iY?+?+9/_^]]]q3+33/_^]933333310473;! !3267# "&"!7o")H(4_qݏ`M:-CeGOh2 )"aKv-\$f@7  "" %&!!dY !!!!]YaY?+?+9/_^]_]3+33/_^]9333310"'$5473;>32!!267"!4&PhPdd[ 1G4%Eem *' ݟ7P!(@G % !&&!)*%%iY %z%I%%% %%!""iYkY?+3?+?9/_^]]]q3+33/_^]9333333310$"&5473;! !3267#"!4&o"P'5_P` ](vwM:-Ce?Wn2 B-\ 'r@>   %% () "$$dY $$$$!]Y]Y?+3?+9/_^]_]3+33/_^]?93333310&'$5473;>32!!267#"!4&hPddH[J 1G4%Eem *"DRb,b&6R@ %&+5+5&6 %+5'F@$    kY iY& ??3?+9/+393333310"#3737 #"&'53254$d_IcS~J{q<Rכ1 5JD@# ]Y aY?+??39/+393333310%#"'532654&#"#335oˈc/lDQ_5;<%HJ;@"iYiY kY ?+?+?+?933310%3##! #"'5326!Ǔӟ1?^J;4=O]m7 VJ;@ "]Y]Y ^Y ?+?+?+?933310%3##! #"'532!𼃶}`v="l#{a %U@0   iY:  iY&??3?+9/_^]^]]]+993333310%!"&'53 !#3!3%T}L{1Vj jJa@9   ]YE    aY?+??39/_^]_^]]_]_]+993333310"'53265!#3!3ц_ni}tR :;J7^@6    iY :      "iY?+???39/_^]^]]]+933333310%3##!#3!3%ɖӠVj'Jn@@    " ]YE   ]Y ?+??39/_^]_^]]_]_]+?933333310!33##!#bT~J7N{J;@   iY  "iY?+??39/+9333310!##3#"&5332673ϲh޸|_%5'Gvu69J=@   "]Y  ]Y ?+?39/+?933331032673##3#"&5L\enlJp7>QG8BE@$  "iY?+??3?39933333310!##!3!3##47#Lǔբ]wRJB@"     " ]Y ?+33?3?99333310%6733###.'#3.較?4%mtN{;^-wJC]Rb,b&$6=R@ %&+5+5^&D6)1%+5)&$j?R@  %#&+55+55^&Dj&8%+55^^b&(6R & %+5+5q&H6 ' %+5yjE@% iY iY iY ?+?+9/_^]+99333310"5>3 ! 5!27!}ڀLr/+T,"pqyvFbh^Hyj)&jsR@ - %0&+55+55h&Hj.%+55)&jR@ $%'&+55+55&j %%+55NF)&jR@ =&(: %+55+55D&j$6%+55H;H@&kYiY kY?+?+99/+3933310 ! '53265!#5!5!dbA]B O00ФJK@'  ^Y]Y ]Y?+?+99/+39333310#"'532654&+5!5! ̢xFɐ|HV}`&MR @& %+5+]5uj&M7  %+5`)&jR'&$ %+55+55u&jB  %+55})&2jR@ -&*%+55+55qh&Rj *%+55}{qh^|})&{jR@ /&,%+55+55qh&|j+%+55=)&jR1&. %+55+55;&jSŴ+%+55&M/R@& %+5+]5j&\M  %+5)&j9R@ ,&) %+55+55&\j * %+55s&SR@ *&U & %+55+55!&\S M!' %+55)&jhR@ )&& %+55+559&j % %+55 /@   "iY iY ?+?+?93310!!3##GqJJ /@   "]Y ]Y ?+?+?93310!!3##J{)&jR-&*%+55+55&j) %+55/j&} %+5jNJa@5    dY   ]Y dY aY#?+?+?+9/_^]3+3933333310"'532=##53!!!!3.9b\+jkJ1bZ_@8     iY9h0 ?3?39/]q]]q3+3339333310!3 3!!# #!}3wfgu9}wV`?L{%J]@9   dY/? ?3?39/]q]]33+339333310!3 3!!# #!s c`{b1J; :@ iYkY?+?9/_^]+9933310!33! $#";FaٽjJyq=G}"Z@1 ""#$piY# kY?2+3?9/_^]+/_^]99333310"&54$!3332653#"'#"!265L("fsֹbp"ϻzj{m̧tio ,O@)*$$-. (]Y!!]Y ?3+3?+?99/_^]93333310%2653#"&'#"323/3!26754&# ri.S}i< iꈁ3WknV)  0MUNT#XH*\@2" +, p  kY+ kY%iY%?+?+9/_^]+9/_^]9333310#532654&#"'>3232653#"&'.ǿғca\abhztmj{9B{JNĥ3Ӑ}x)̓N^%R@+ !!&' ]Y&]Y]Y?+?+9/+9/_^]9333310%23# .+53 54#"'>32Jײ~s!NO;Rnjv3IdY$"'%9}dH$W@/ %&kY " ""kY" iY ?+?+?9/_^]+9933333103##4&+532654&#"/>32 ¸ߠgk-/ebj{8C?T4lpݴ6wm"̓s);J@@"]Y ]Y ^Y?+?+?+/_^]93310323#"&5! #"'532!fsϴ`v="l#|59a fe@:  p iY :     iY?+??39/_^]^]]]+/_^]93333310"&5!#3!3326539Ƕlonm-Vjσux)Jq@B   ]YE ]Y?+??39/_^]_^]]_]_]+/_^]93333310!3323#"&=!#b>hsϲ´J79}3nJ}=@ iY iY iY?+?+9/+933310!! 4$32.# 3265!b@Ty]FYa XaU0*'/q^E@% ]Y ]Y ]Y?+?+9/_^]+933310!! !2&#"3265!B"ݪ=ƽHF),PJ֜@@"   p  jYiY?+?+3/_^]9333105!!3253#"&5>5spsu))J>@   ]Y ]Y?+?+3/_^]933310"&5!5!!32653jjshk;̓}z9smd']@3%$$ ! !()%kY: kYkY?+?+9/_^]_]+9933333104$32.#";#"327! $54675. pbgjǶǯϺ\EKB5yl{\MǖX^j@@#   iY  iYkYkY#?+?+?+?+933310"'532=#! #"'5326!3;?.8b1?^J;4=O]m7 jkVjJ@@#   dY  ]YdYaY#?+?+?+?+933310"'532=#! #"'532!33232673#&'#57673\;:ZF!p$GC@(*] dL%IE>(* \ edbfo\yb6o60w4;DhxcE$.2js$/1jsBbSQ%+55s&$'dK/R@ &&(%'!%+5+5+5^!&D'dK&,%ߴ?9%+5+5&$xR@!% &+q55+55^&Dx19%+55&$yR@ % &+q55+55^&Dy08%+55X&$zR@!)% &+]q55+55^&Dz9A%+55^ %2@ 43/( (((,& &&@< H& 0 "  iY ?3?9/+9/_^]3^]/^]]q33]+q22/]]39310!!#3 '".#"#>3232673 332673\;:ZF!p$GC@(*] dL%IE>(* \ elOkbXm ;DhxcE$.2hq$/1grE<@A^ &D{@H%+55N&$'N1bd@&"(%%+5+5+5^&D&Nd4:%)1%+5+5&(d  %+5q^&Hd " %+5&(cR@&-  %+5+]5q&Hc @) %+53&(RR@  &! %+5+5q&HR  %1 %+5z&(tR@ % &+q55+55ql&Ht  " %+55N&(uR@  % &+q55+55?&Hu@ " %"&+55+55AJ&(vR@ % &+q55+55q+&Hv " %+55b #2@) 43%'**.:.. 0*@** *   H @2 H   iY: iY iY?+?+9/_^]^]]]+/3/++_^]33^]r]99933310)!!!!!".#"#>3232673#&'#576731Ty$GC@(*] dL%IE>(* \ edbfo\yb6o60w48$.2js$/1jsBbSQy@* @?136:*::6 6@.2H6@ H6 )! H@ H,$ iY iY?+?+/3/++_^]33++^]]99993310! ! 32#"".#"#>3232673#&'#57673_G>b|g$GC@(*] dL%IE>(* \ edbfo\yb6o60w4nheq,&%)$.2js$/1jsBbSQ73'673#dpcrae3w0GPI6Q{gK[eA:Eg[plb 3@ @ H   _/]]33/]99/]+10#&'#57673%#&'53farjid5q3>byV9FAe`F=JY[suXj d@!@ HD`pH@ H   _/]]33/]99/++qr^]+^]29/310#&'#5>73#'>54#"5632dpcrae3w0GT ;>c/8K[eA:EgxfO %>Tf&K@1 @H @ H  @ H 5"" """_/]]33/]]]9]+2/++3310".#"#>3232673#&'#57673-$GC@(*] dL%IE>(* \ edbfo\yb6o60w43$.2js$/1jsBbSQCBq5@"$4  /  _/]]33/]3_]]10#&'53 332673bwV.O9lQi`Zm ^qeh G>ADqf@$H@ H */H$H@ H/_/]]33/]33/+++r]r29/++310#'>54#"5632 3326731}T 9>a%$>lQi`Zm yc)\ #=P G>ADf $E@. @H @ H  /?!/_/]]33/]3]]2/++3310".#"#>3232673 332673-$GC@(*] dL%IE>(* \ elOkbXm 3$.2hq$/1grE<@A-=q@   //39933104'3#"'5326݋id@7#5%3gw[js /j @  kY#/?+99310"'53253;?.8bjk3\&7zF %+5!F&Wz %+5{)t@B'  ' '*+ _Y ]Y  $]Y?+?_^]+??9/_^]^]3+3999933333102#"&'###5353!!36"32654&o7K oǦ\POxׇ=qqh$-t@> && ** ./ %%kY: $ $kY &kY?+?+39/_^]_]]+99/9333333310"#.5463! #!!2654&+!2654&#5} &'g=1B} /nxj}{#E@#! ! !$%  ]Y]Y]Y?+?+?+?99993333102#"&'##!!36"32654&o7^V oǦ\POxqq J@*  iY :     kY?+?9/_^]^]]]+993331032654&+3! # qż  { u9@  ]Y ]Y?+?+?999333310"3363232654&#" o⧓(qq3н?&@ iY iY?+?+9310 #"&'532#"'6D[qWJv!:<5PV}$G@'& !!%&kY/ iY iY ?+?+_^]+99333310"327# 4$3254632&#".9]p?|tn~==19`JD):"hTch1q^!:@# "# aY aYaY?+?+?+99333310"3254632&#"&#"327f 8Mm~54&#"vĬhNLhR`mլ{ªZMc.@+=LAEk[u ҳ~E-֡{ S@0   iY:  iY iY ?+?+9/_^]^]]]+9333107!!5!!5!!{yT1Ϣ ȢJyjof']@3%$$ ! !()%kY: kYkY?+?+9/_^]_]+9933333104632.#";#"327! $54675.؄dXkjƻ߸ݿ`MK}I4}h{kZϜQ@1   iYI  ? _ o    iY iY?+?+9/_^]]+933210"'53265!!!!\B1*3H91RSUX}'Z@2) %%'()kY/  'iY iY #iY?+?+9/+_^]+93333310!# 4$3254632&#"&# !27!BtW钆n~;@1:`F 3%&cV##clT#B@"!    !  iY?+?399333332310%#"&5436734&'32DEjnR#"''E݆MyvUhs6AM-?:$E@$"  %&]Y ]Y ?+?+???993333310%2653#"&54&#"#33>32ykt 2c}bA8Z@UU@ iY ?+?993103267#"&5oJS,^p8cb tFoX@,  iY nY nY?+3?+39/3+3993333333310)57#53'5!3#b𬸸j' )jj)'<@     kY?+?3?9399333310 #&&'#3676>32&#"V=p9B,O;iT>(*0"<-=QӈHL2MA(63A@"      aY?+?3?93933333103?3 ##32&#"`=F_D}CB/;/2NTs+mm6A D@&  _Y/ ??9/]]3+3933333103###533b\+ՇV!&d@(# '(@ H""  ]Y ]Y?+?+?9399+9933333210#''7.#"56327327#"&'&'# /'D;>5DCm3&n/$%2CJZ U!P5A=.( VcDB96 J[S~u$>@# #%& $  iY ?3+3??339993333103265332653#'##"&'##"&5qvw 3w- :~tJWedhbj N6@   iY?+??39999333321033&53###"'53265-  B1*3H9Gs'B9JQ%SUL^}{}'E@#"""() % %iY iY?+?3+3?939333310! ! >32#4&#"32#"O6#9{¸vl'mqieXc>?,&%)q^%G@$!!&'  $ $]Y ]Y?+?3+3?939333310#"&532>32##"32654&# 5vف5W>G'Ӌ ,KHIZF@#  kYkY?+3?9/+9/933331032654&+7 !###"#.5463#Ķ$騹5} ׍Rg=1B}{ -J@(%  ++./ aY!]Y(]Y?+?+?+?999333102&#"3>32#"'##"32654&CB/;/2 @nw 裑6A=N)ZPҟ)N==#3N@&   iY  kY  ??9/+39/+993333331032654&+#33 #۲Ѹ+~Eqep\`%;@ &' iY#iY#?+?+93993333104>7>54&#"'632327#"$`R}7:ϟ>E{cr?4M_GepNRʫK:R^Cn~a"-\m^#=@ $% ]Y"^Y"?+?+99993333104>7>54&#"'632327# \>ftpg>;~ls0J/LnX4EO=>GFJLjU<)@?-PRXEJ^p"O@.$ #$]Y  ]Y ]Y?+?+3/_^]q+93323310"&546323267#"&5";54&{zJS'em4d,$eO2Vxmnvoda 51RH?!FP@(     dY ]Y aY?+?+?+333/9933333310"'532=# #5?3!!3267C2%$-AKJ2FJ5FKR'[^ 69  ’N_IoWNDW@0   lYiY  iY?+9?+99/_^]3+393310!!5!3!!!5!y5 lBФ%PsJl@=   ^Y5EedY  dY?+9?+99/_^]^]]3+393333310!!5!3!!!5#uIT =w{H;H@& kYiY kY?+?+99/+3933310! '532654&+5!5!T|dbZrǃO00qdF@% kYiY kY?+?+99/+39333105!!#"3267#".54>7]dc\ڈ{ގ%c00,#ỏuFJI@& ^Y]Y ]Y?+?+99/+393333105!!#"327!"547}Fx̷ǃ}VH9J$f@7""%& ]Y    ^Y]Y]Y?+?+99/+3/_^]+933333331027#"&54632654&+5!5!#"zйƾxv'lgmJ54&#"'6323!!!57!81zl]K`+34}9g`wZZYgrDCyǬV[!C1 }H;C@# kY iY kY ?+?+39/+933331032! '532654&+#5!Vdbun̈O00"DJC@" ]Y]Y ]Y?+?+39/+99333331032#"'532654&+#5!/򄷽ᄋGVmlmjJXF!P@(  "#@  dY^Y?+?+3399933333105#5?3!!#"'532654&'.Gk=*6؀|caIVHEA?jEXXJ)%+5+5q_!&G']L{@72&'%X#*9%+5+5{&/-1 %+5&/M1 !%+55&OM W %+55{&1- c#%+5&1M c/%+55e&QM S 0%+55&$L/m@ %&+5+5^!&DL2-%+5&,Lm@ & %+5+5c!&L  %+5}&2Lm"&$%+5+5qh!&RL $%+5&8Lm@ &%+5+5D!&XL ! %+5&8 LR@!&-,%+555+555D&X Lu@ 0/ %+555J&8R&@ !0!@!!&$.%+555+q555D&Xs@ '1 %+555^&8 KR&@ !0!@!!&:3%+555+q555D &X Ko=6 %+555J&8R&@ !0!@!!&.%+555+q555D&Xu1 %+555h^W@5    ^Y    / ?   aY]Y?+?+9/_^]q^]+9333102#"=!.#"5>267!Xj[^ m-' !&$ LR@ %&+555+555^&D LJ8&%+555&$ O %+55^&D NJ54%+55&MR U@%&+]5+5^j&M״>= %+5}#l@= !# $% lY #iY/  iY iY ?+?+9/_^]+9/3+3933333310!3## 4$32&# !275!5!5!BtWF -͒%&cVVT#q^".@K!-&" "!/0   ^Y  / !  *]Y #]Y@H@ H]Y?+?+++?+?9/_^]3+39993333333310%7##"323733#!"'5327!5!7%26=4&#"oy uaSlū" *($FVf=!h};s&*LR@ &&z(#%+5+5q=!&JL 50%+5s&.LLR&ʹ%+5+53&NL{@  %&+5+5}=&2Q} )"%+5q=h^&RQ "%+5}=&2'MRQ}%@&)&"%%+5+5+]5q=hj&R&MQ&!%%+5+5H;s&LR@ '"%%&+5+5!&Lr&!%+5 &'= 4%+5 J&'] >%+5q_&G] X#*,%+5};s&*vdR@ %&%!%+5+5q=!&JvJ D2.%+5\@4 iY:  iY?+??39/_^]^]]]+?93333310#3!332653#"&5^^`[aȳVj]fg^V;@  jY iY?+???+9993333102#33>$4&#"K[ LJX(qjˊ Ns&1CfR& %+5+5L!&QC %+5s&$sR@ %&+55+55^!&Ds4&%+55>&$R@ %&+5+5^&DT1)%+5s&(sR& %+55+55q!&Hs+% %+55>&(bR@ & %+5+5q&HV ' %+5ds&,sR& %+55+551!&sV %+55>&,\R@ & %+5+5E&%+5}s&2sqR#&'!%+55+55qh!&Rs'!%+55}>&2!R@ #&#%+5+5qh&Rm #%+5s&5sRz@ $ %!&+55+55#/!&UsH! %+55>&5}R@ ! %!&+5+5/&U  %+5s&8sXR&!%+55+55D!&Xs$ %+55>&8R@ &%+5+5D&Xy   %+5NF^(L@)##' )*'(('^Y((( ]Y  ]Y?+?+9/_^]+99333102654&#"'>32#"'532654&+5=~V=Z_򂂥[aΡӏqq(+ŭ},*͖|L+/%s&+LR@ & %+5+5L&KLN{@ /# %!&+5+533@  iY ?+???99933310 #33>3 #4&#\ B}-5]tdǶq'Ew%L@' ""&'$$kYiY?+?39/+9993333331026=3!"$&5%&533265! 엞1縠༹èc0ћyA]_*Jqh(L@'  ##)* &&]Y ]Y?+?39/+999333333102653#"5%.5332654&#"my^i i\yᓞ'3ٞKb'NjD&=}  %+5PjsJ7&$OR@ %&+5+5^&DO5&,%+5&(z{   %+5q^&Hzo " %+5}&2 L!m@'&32%+555+555qh&R Lm@ 32%+555}&2 Mm @ !!!&!-%+55+]55qh&R Mj!-%+55}7&2OR@ !&%+5+5qh&ROb%+5}&2 O'&%+55qh&R Nm '&%+55&<MR@  & %+5+]5j&\M  %+5P@)  dY  dY ?+?_^]+9999993333103632#"&''672654&#"?M|^&'JV7<3?6>?mrG<=o=m=-561^",o@; ++&&-.+ )  )dY ]Y#dY?+?+??_^]+99999933333310632#"''674&#"#33>322654&#"L?L|S(JVw 3oă4:>6>?mr9s=mJQY55561F$m@8 ##%&  #! !dY    @  dYdY?+?+33_^]+999999333333310#5?3!!632#"&''672654&#"Hk=?L|^&(KT84:>6>?VHmrG<9s=j55561qV'3T@,1&& +  +45  #..]Y((]Y?2+3?3+3?9933333310"323.533632# % 4&#"!2654&#"Vw  orr-" .9qqмVqV^(4S@+! , '2256 )]Y/$$]Y?3+3?3+3?993333333102#"'##47##"3 > 3265!"32654&qv  kr:kӑᐟ^ҡ#Ki^pq* %|ZϽ߿fd@7  /     iY  ?3?9/3+3_^]q993333333210#!###37&'3щӎ;>V(!l\N_;Tq^xcE }f&d@8 "$%$'($ '@")H@ HiY iY?+?+++9999933333310&'327#"'#7&4$327"&y'=@JI#zI[]p_b5C?NJ(p :"RbT SJqV"\@0 #$  aY aY?+?+?/999993333333310&'327#"'#&;#"զ9+7?#9Hr]] L2@;PP+ g =@    lY  iY ?+?9/3+3933331033!!!!#\ɳ9}f\D@%      iY?3+33?_^]93333103###!5!7#)-`Ϗ^7Y-^P#C^/h^2Q@*#0)034!,)0!&]Y!^Y ]Y ?+?+?+999933333103267#"&'&'&'532654&'.54632&#"%"'YF`E,|w~;=ptd>6b "XXJAZ:54&#"'>32׊J;DKj7sy8,6=Ѷ\3^-@   ]Y ?+?9/3933103>54#"'632FACȹ'750r˼V )@M %!%%*+iY  !!kY8!!i!!! !!)kYkY?+?+9/_^]]]q+99/_^]3+3933333333310#53! #!!!!2654&#%!2654&+Ǩ&/'^ ˆ}nxjO@'     iYiY?+?39/33+339933333333103#! =#533!26=!ܤ !͠AA·ӳif@W    !@iY: iY iY ?3+3?3+39/_^]^]]]3+3_^]93333333333103#3!!!#7#!73!3#et)''GXrF^8^8 qV#'+@O (*+'"&# $$#"+*,-*(&! '(!!(^Y!!!! ]YaY?+?+?9/_^]_]+999999/93333333333310&323!3267#"'"3&';q}R{>YXj[mkZ-kbZT`VL99m-' Nu6ʸO``{?@   iY iY"?+?9/3+3933333210"'53265#5333#^:GMdd{yr{m!Y@0  "#cY`   ^Y " ]Y?+?9/3+3_^]]+933333210"'53265#5333#4632#"&-^@ECNI%=-*??*-=UWC`_<66<;88}7-I@&)/# --./!iYiY+&iY+?+?+?+?9999333310"32>54.47##"$5!2373327# ʞ[\" 9奻G#; :G2*/C+\<[6]`pVancWQBq^ (K@'$* (()*]Y]Y&!]Y&?+?+?+?9993333310%26754&#"47##"32373327#"R su-8@&*e%՘n<,  /#pU!VK@%   kYiY?+?39/3+3399333333310##53! #%32654&+۲\\eq\/^R@,  ^Y bY?+??9/_^]3+3993333310!##5333>32&#"3d?eI8=:ump L@'       iY  ??399/33+339993332310!33###533!RƏ{y{'/1)J!U@, #  "#! ^Y ]Y?+?39/33+33?9933333310#533!33##"'5326?6!͹‰uEKJ2FVx&9Xo?= Nkk _cj6I\D}H ?55q=^<@     ]Y]Y?+?+??9999333310"32373#'#'26=4&#"3wsƤ( .!{^@J ?55{*E@$ ((+, aY]Y%]Y?+?+?+?9993331032&#"3632#"&'##"32654&EB/;/2 oo7ꦐ6ArqqPOxǼDf^(@ aYaY?+?+993310732654&#"'>32#"'V7271^r@";b^']@1 %% ()]Y  aY "]Y?+?+9/_^]+99993333310"''67&532&# 632"32654&}+ +@N T28bŽ~wRWiQbQa?~n+"4`iNs^M<09q',M@(.*#  -.']Y ]Y]Y?+?+?+?99933333310327# 5467##"323.5326=4&#"=1DI,/m  vw  j[!Vw*  .ym!q)K@'+'  *+ aY$]Y]Y?+?+?+?999333331032&#"#'##"323.526=4&#"H?/;/2sw  Ǥ6A( .y#!h^GH@h^W@5    ^Y    / ?   aY]Y?+?+9/_^]q^]+9333102#"=!.#"5>267!Xj[^ m-' !h^#+e@4-)((,-!aY ()) aY $]Y ?+?+99//3399999/+93333310#"#"=%.#"5>3273272>5s{KXj[m ,#>.RT9\F N ȅ-' Ŵ/zUK7NYX^D^D3^0{@E2%  ++/%12aY# /00/]YE0000000# ]Y #(]Y#?+?+9/_^]^]]]+99/+9333333310 54#"'6327327#"'#"'532654&+57O_?ԑ*o">.OW'1}?L/}v򄷽(L[U{UK7"._$$gGV^\^[qq^#e@9! !$% ]YE     ]Y]Y?+?+9/_^]^]]]+993333310"3 54&+53 54%2# (V98u и^[9$g((J?@ ^Y ]Y ?+?9/3+3933333210333##"'53265#^@ECNIC`UWo%2U@-4%0 )  34 aY-]Y &]Y #]Y#?+?+?+?+999333333310326=7##"323&=32&#"#"'26=4&#"Šoy F?/;cV+) 2u@wF%+q=^Jq^=@ ^Y aY aY?+?+9/+933310%#"!2&# 327#5!xj#{Bi9+"#+JH`-J$G@#&   %& " "]Y?+?399999333332310%#"&546733>34&'326mQ4gj9L`<*  $+B)#$(--EooOv.!^n22:<2;42^ 1K@&-3  23 ##/]Y*]Y?+?3+3999993332310%4'326#"&5467&#"563236?>32&#"RLL--ll8S&.%.:4G'. !D'I2;-%."XgkR1+)kg~~iHo5 )7I!32#4&#"#CB/;/2 1qʲw6AZ@PZ5L(D@$((")* aY ]Y %aY ?+?+?+?993333104&#"#32&#"3>32#"'53265wCB/;/2 1qCB*@/26AZ@PZh6A X@1  cY`  ^Yx ??9/]]3+3_^]]+933333103###5334632#"&b=-*??*-=)<66<;88JJFJ 9@   nY nY?+3?+393333310)57'5!Fj#-%kk%# T@1   ???9/]3/]339999933310"'#&#"#>32332673#+11i sb#+01f u b;3 3>32#"'5325#ߙmt /jN 5tCB*A`ÂJPZX`hwL^<@    ]Y]Y?+?+??999333210!"'5326533>32#4&#"b]2/;H7 3oIJw!YlݖQY55^ >@"  !"]Y ]Y ?+?+??9993333103267#"&54&#"#33>32L5H?O+w 3oēj[TJQY`J,@   ?3?39999333310##3.5`8 JsoJ'{qh^|q^#{@F $%  ]YE]Y]Y !]Y ]Y?+?+?+?+9/_^]^]]]+99933333310)5#"&5325!!!!!32654&#"/ŕ| 'o +qӕs^%B@!   &'# ##]Y#  ]Y?3+3?+9/99333104#"326533267#"'##"5! vi_fe]hzϸE AgKBh| 󀊬5Xo\JUNJ ?5(@  bY?+??9993310"'732>53#'#I8A6WU> `gkrJ7@  bY]Y?+?+?9933310327# 5467##"'732>533AL)/n >dI8A6WUlY!Vkr `gJ/^*@   bY?+??99933102&#"#33>I8=:WT?^ `g6mp/^3@ bY]Y?+?+?99331033>32&#"327#"&5?eI8=:WTHT=@DRJmp `g#da!^@ aY?+?9931034632.#"R^N8HG!Zc%^@ aY ?+?993104&#"'632jGH8N^RcZ! XJ A@   ]Y ]Y?+?39/+3993333310!#!2#4&#!! m΂~9vt LJx 3U[XJGoJ@ ?55hy^/M@'# )01,)!&]Y!^Y ]Y?+?+?+999933333310#"'327#"&532654&'.54632&#"y^FHS=@DQ|w~;=ptd>/ da!kXXJAZ:H7!Yl\V!YkLZ@/  ^Y]Y ]Y?+?+9/_^]_]3+393333323103#!"'53265#53!2.#"b]2/;H7\4>H7n!Yl<V!YkL^(@ ]Y]Y?+?+9323104&#"56323267# 87../V}}6I>4\dS!PlY!VL!P@+#  "# ]Y]Y  ]Y?+?_^]3+3?+99333233103!2.#"3##"&5463267#"\4>H7B5ZV!Yk9k{Upcb-Zf@?    dY/?O]YO_0?]q]q+9/_^]+3399333310"5>3 3#5!5!4&OKi0BHj>ZVH{\i!F@@  @  dY]Y?+?+339933331027# #5?3!!`9f5Hk=[ TVVH_fJh@6    ! ^Y  ]Y?+??39/_^]_]33+3399933333333310!33##'##"&=#53267!X7 1wɎwJNNOVы7=JF@$     !  ]Y]Y?+?3+399933333310#".5467!5!32654'5!mjoh뚘P2-H^/@ aY]Y?+?+?933104&#"5632#"&33265=P:;F;ߴlQoJ @     ??393310 #&'##qF)J\`{LJ3J"@  ?33?3999103673#.'## '##-("-- ,} &1JeiiJi(W&AJ+@    ]Y ?+?393993210!#&'##>32&#"HDCW?5D^t"9fhjϲ fXJ"@  ??39932310!#3 3Bsw{P\JG@& dYdY ]Y?+?+9?+9933310)5!5!!3267#"&5NT5HCN+}wGj[ PNBJ]@4   dY   dY   dY?3+39?+9_^]+933310!'7!5!5!3>32!"3254&),1NYviO7e6,ogxvtS[| uddBoZ:FZr6,fj90>K3-@   ]Y ?+?9/3933103>54#"'632G?CǺ66.s̻Ww5OGh@3-@  ]Y?+?9/393310#"'73254&'ОC>FɴmVr.69q^(@  aYaY?+?+993310"!2&#"327fP37br!4@;}&2y@?!o!!!! %+5]5XJ\\^"e@9   #$]YE]Y ]Y?+?+9/_^]^]]]+993333310 !3# !2654&' !"&54675&54697:V)uǚЗحg%9q%M@)' !!#&'$#^Y$$ aY aY aY?+?+?+9/+93333310%#"!254632&#"&# 327#5!xj#lVn~;?/;`Bi9+"#+bH`-jJ=#]@5 $%!cY` ]Y ]Y?+?_^]3+3?_^]]+9333231033##"&546;267#"4632#"&zXh9-Ny=-*??*-=JmzVocb<66<;88J6@     ???3939333310# 373#7O4$|} i8ulNVJ@]Y?+?993103!!XJLq',J@'.* #  -. ]Y']Y ]Y?+?+?+?9999333310!2&#"#467##"323.526=4&#"m/,ID1  vw  ǤV![iMw*  .y#!3R@+]Y  ]Y?+?9/39/_^]3+393333310!#53>54#"'6323#G?C߿P86.s̻W5PR@+ ]Y ]Y?+?9/39/_^]3+39333331035&54632.#"3###ݯӜD>FţYs.67Pq^%(g@8# '' ()*'dY&&dY   ]Y]Y?+?+?99?+9?+9933333310"323.53!!!'#'26=4&#"3w  TNsƤ{L( .y6ȋ!=Eq-:@F- 8(1+%1;<%"^Y-++]Y+)"5]Y".]Y ]Y?+?+?+???+99/+3999333333333310#"'532654&+5!#'##"323.53!26=4&#" ̢ysw  ɐ|HV}N( .y6!qN-%25>@R950 )#44%5<<5 )?@ 6dY 49 dY%3##3dY#!-]Y&]Y?+?+?99?+9?+9_^]+93333333310%3>32!#'67!'##"323.53!26=4&#""3254& Wwi(!9sw  {L8e6,}XT^9P)( .y6!=EZam1!F/a@2 ,,*!!*(01 @$!(]Y + +dY /]Y?+?+33?+99933333310#! #5?3!632&#"2654&'.547!3Hk%TX>otdN{t~;!`L/TjVHJFG>H7U>[!Yl SVHV!Yk+_f!F/:@O+%%#3 88 #%;<3 0# 0]Y  ((.aY(dY5  ]Y ?3+3?+333/?+9/_^]]+9999933333333310>32# '# #5?3!!3267&532&# "32654&_]ǡycHk=RCKm- T28bk>eRWiQ!OKF;sZISVHXm;Rp+"40G{M<09?1g@7%'/23'+!]Y+ ]Y+%%dY%]Y?+?+33?+?+?399333333310"'53254&#"#!##5754632&#"!3>32W;>=v}il0]F[X 6jȏkBT>?%xGVT&J@&  '(# ]Y ^Y?+?+??9993333310#"'#33 54&'.54632&#"ꬴ@w~;=ptd>/VBlAZ:32Ϣti&LR<032#4#"#2H;+3(Hti=G<(9FR!\ 5@ @Po V?]2/]393332107"'5326534632#"&TIDI22*<+,65-+3;>>/]~ 0o lE@gU1y?!@    V TU?2??9993310"'732653#';>B*]~ 0ty leW1!8@    @ P  VU?3?/]399333103267#"547#"'732653?'?/]:kM;>B*]~+B? !ABhT l J@)       /  V T?3]?39/]]]339933333103#!334+326Z\yRG{Xv@{@'"@ VT?3?3399910&'#3673?3D uv^Ff@3@II_7Y1g'RT!\/@  :  @ P  V?2/]9]39310373#"'532?$66nQ4I(q3&-_EZwdN NP + J -@ / /O_/]q33/]2102#52654&#+hxzf2A;8Juderf;66:+ J -@ / /O_/]q22/]310"&5463"3 fzxh2A;8teavg:66;'!*@ @H /29/+3933105654&#"'632RH/l*-n8;J"jDoMk!8!GH@3RI/10%5% ~R3P3RI/10-53~P3'^?/103# '3P^_@/10#33P@+}!v!C+_}H H++]5ydM@ p]5^^!J!@??99//]]10 !lJ!-J@ ?9/]10 J+ \+ \VV-7/210!!R{\7 @  _/]22/310327#"'9">/QT%p}KZ%zUK7N3#Z >@%  !" @P@P V?3/]q399933310#"&54673>34&'326.4oXXn.4½! ż  X?VspY=_7R=)T--T&'P@ T??9310#3Pjy!&@  "#WU?3?399333310#"'53254&'.54632&#"ᵩnxMo_/;eJKBpsw9Nh*;)0@Q;jy=:,&%428s+d 4@     V T?3?39993333310 33 # #`7/hX+D"@  T??39933310.54632.#"dB8z1Exa'-g*@ /3/99310!#!5!o @  //9/3993310!#!5!3oR$@ //9/]3993310!#!5!3o^ @  //9/3993310!#!5!3oV@ //399310)5!3@ //3993103!!$@ //9/]39933103!!#odiL  H H #?++]5N\@@H@H@ H+++55 H/+3?910#3dۢ%9H/+?29103# #d%=hj/@@H/+]?10%5% jNdۍhj/@@H/+]?1075-hN/d܎D /]10#.'53wCh-D476>? /33/]310673#%>73#S\!ByP&h FyZj;30G68?  /33/]310#.'53#.'53yA &c&y?#j!?39P.06M(}@     /]3210".#"#>3232673(OLG-2fqZ)QME,-h n#+#5>|#)#3>|hs@ `/22/]10!##Tmsmhs@ `/33/]10#5#5hmsmh; /22/1033mTmh; /33/10!5353hmm)V@  /]33/]310!3!53nsuVR)V /210!3!nsVR) /33310 5!!+Rdy{[!K2jMV+@@H@ H/++]210!!VV?NjO  jwc Po!S[!LR`?]10#RO @ `?3]210#!#ROO= %@ /_/]]22/]3210"&'3326734632#"& nTtda p =-08:.-=يF<>Du<7>56=8= #@/  _  /]]33/]2102#.#"#> n Uqg`p 슉I8@Ad ?10'63 4|B%f ?10#67 4|B%d ?10#'73%B|4 f ?10#67 4|B%3^ @ ` /]]10#.'53yK%v3^<89<3^ @ `   /]]10>73#5m!,?wwD?@1LB H/+9/310353#5#ᇇᾅ{LB H/+9/310##33ᇇDžmj@ _/]210!#!ڈjg-q /33/10>53ps"3s  /33/]210"&5463"3sgyxh2A;83vcavf;66:)V@ /]3/]33103!535DRb{{)V@ /]333/]105#5!#DV{{)- -@      /q33322/]/]q]1053533##5ד{{2eM@ p]5V kY/+/10"'53253><.8bk7jV kY//+10"3327b8.<-k ej@/  ? P  ]q55 0PW 2H ?+55~;99zY=Q6`RH H++]5Bm//]2/310!#5!#ڈ6b}& @ H /]3/+33310#"'#"&53326533265wjo55ohwop3@bs3@}q|GGzsBEBEi[L  H H #?++]5g[K  H H #?++]5?N H+]q5= H+]q5xR@ / H+q52eM@ p]55H/310!5!jŃY9]N@   /33/]210".#"#>3232673&HEA,* h eU(KE?**g d%+%;w++/10 L9}j ?/10 #py3s   /22/]3102#52654&#mhxxh2A;8udbug:66;Bm@ o/33/]310!3!53m&ʈB\5-@  0/33/]310!!35#fٴ-}$ @ H /]333+22104632632#4#"#4#"}wjo56nhwnq3@bs3?q|HHzsBEBE/3 "@o   / O _  /]q1077''7V{yX{{Xy{VyX{{Xy{VyyV{}@O_/]10463"#52654.r<;%+%t<;%+%FK]g.5>G(L^h,8>EW[@/?o]55S!C4K!v,xR~n93?5>xU@ @H+555=B@ `p/33/]210!#5!#B|W9[ `H H++]55B@ _/]22/]10!#5#|{w-<@$ / /]]2/]3//999910"''7&#"#>327326739[L\J-11i sa:LE\C0$01g v/}8x;32326734632#"&4632#"&+SOI"11i sa-UNH 01g q8(.2:&(88&.2:&&8%+%;3232673".#"#>3232673'MIF&*h hU*PIC+&f eW'MIF&*h dY*PIC+&f f$,8pz%6/pz$,8k~$6.n{?f  /33310%35 5#F /]9/3105#7#Bxx% !'/7AIS]gqy@w  &$622?2O2_2?O[ooVjv~~rzB88F< QeeL` .*0*@**$2jz<`**`j=-08:.-=n n Uqbd p L<6=56=8I8=D=7  /1077''7VidaegVidaeVfd`diVgeadT @ 0O_/]]10&'5673_x,uHmghG:,gT @ 0O _  /]]10#567&'5g4V)iSRj K.iH34f#@   0O_/]]2910>73#&'##567&'5 YRh,:,!hd/_'nO39CT2=@@% HO/O_ /]q333/]/+q10#7#73Fi%Fi%T) @ P`/22/]310 $'3!2$73qgUJOar)ƻztT3;@/_]5Bh@/_/]310!5!4בBi=P+5T-@ /`    /]]r33/]21023273#".#"#svhuuh.&/&}&/&}T3 /@"P` ? O o  / _   /]q33/]210 #&!"#6$b/UOa3ƻztT?/22310!5 5!+)%#&@ ) 9  X[Y?3?3?9/q3910'#"&54%754&#"'632%26=5fBoyV`?92g0+wRdQlc<5eA0na K<$h?ny3cZV/:?0.)3/@ ;/@ H[ Y?2?39/]+q]q310"&54632!3267"!.%14dQ8nfDQ 4G)ŨN!}RWMJZ5R@ ZX??]210#3'4632#"&H1# 00 #15+''+((()J  [Y?3?310#"&5463232654&#"J]WX\po)/@ Z XY?3??391032653#'#"&5^Y} &k<NlubVc2=w)  [Y?2?310"&54632&#"327=lX)i4XVYjN)+q#pw/{+)=(@/  @H X[Y?2?3?+q9910"&54632&53#''26=4&#"uOz $f.aOU]RP)e <Ce3>sknqo5/@  @H X[?3?3+9104#"#3>32^Y#o95iz*68wG 5"@ZX [?333?33?99104#"#4#"#3>32>32fvZLyTO} )_9=#vBzz5idkxd?2y<=xG)5@ Z X[?2??9102&#"#3>w)9AKj'Z t]TH)/@ Z XY?3??391032653#'#"&5^Y} &k<NlubVc2=w5X ZX?2?3103673N 5sWA\<V5T @  Z X?3?39910 373#'#T򤤢N)o@  `?]9910673#)VD;8we*)=@  `/]]9910#5673,XywC;f=Df^Cq^&FOb!@0!P!!!!!!%+5]q5Df^&COd$@0!P!!!!!!%+5]q5?ffJ(3`@5+&&1 145#aY .]Y  )]Y ]Y ?+?+9/_^]+_^]+93333310>32#"4632#"2654&#""32654&R/3}v~^ft1 £_+E[fdsGYo~zyuȋ}T{D}RF $.?3;D'TQ@ &%+5?5)&QjR@ +&( %+55+55o\^)\@0  " ( *+ ]Y%]YaY?+?+?+??99933333333210"'532=$47#654&#"'63 3327/D@3+9VT5qD^!<@!  "# ]YaY?+/+999933331032654&'.5!2&#"#"'sX\gnUe>zɪrNPB7: PNû} V@1    iYI  ? _ o    iY?+?9/_^]]+9/99333310#!#!!}XjJ X@2    /    ]Y?O ]Y?+?9/_^]+9/_^]99333310#!!!#!d6RD)#E@$ !!$%iY kY kY?+?+9/+9333333210!654&#"'632!327#"&547v4*0$/CP%9{5-9.(@C'1*.qf>eweI"<=~8uOBq\S3H@&     iY?+?9/9/993333210!4''&''&#"'>3 }{O5Rl\?V[~D\y/!R;V J64D9,SfQ@-   / ??39/]]9/9993333210%4''%&''%&$/#-*M+/wȫ:L VL](?~[fu.G@$'# /0 ! iY '(iY'#?+?3+3?339993333310%##"&'##"&533265332653#!5!26546 3w- :~vw zWedhbj tc䢓~*B)J,O@($ ) ,,) -. $%]Y$  ]Y ?3+3?33/+99//93333310%# '##"&533265332653#!5!26=472hN 5tߘntFSWX`=^=:BFs@@   iY iY?+??9/+9993333310&#"32653#47##"5432;cnͺ =؂x/J/`\k1q?`<@   !  ]Y]Y?+?+??99333310"32653#47##"32&!y} 2qY#/1ո8TFQY(& 9@ iYiY???+9/+99333310!#3>32!"&'53 #"G]UF{w^L>=g1s6E #J7@ aY aY ?+??9/+99333310>32#"'532654&#"#3b<~Sljn~d}.2<=b#J`-T@+# ++ #./'#+  iY  iY ?+?+9/_^]9993333310".546323267#"$54>7>54&H{{ϟ>acR}7)crL@mBɬK:R^Cn~<9dcr?4M_Ggn1^*V@-*((""+, " %]Y]Y?+?+9/_^]9993333310&54632327#"$54>7>54&#"=ڻۼƄ?YYʋswfps+bU;cmQ^.-nZ32&#"! !)U/0##!/D?X~G8JZ<@D0!"2B.1'qCcoY.E]dDo!!3^"G@&  " #$ ]Y  dY ?+99?3+3999333107! &#"!5'.#"'>327>32dw.7"_d$2% -1+F`)^\&`G8CZ (2{{f3# =:9<}!R@* "# iY iY iY ?+?+9/_^]+9399333310"3>3 ! ! & !"/6Tۘ'LoC'JB)XNdZuVPb˶qb^#?@   $%]Y ]Y]Y?+?+9/+99333310"!2.# 32654!"5>32m0ı6ILL3-i~&;;!Pӌv.(#/xj)J C@"  !" kY ???3+39/3933333102#>54&+##"#&546;3)3 >324&#"7>267! pv7Gg,6o X^Qj Wąa^Hv ~E{uT(6S]U] o ,%"gV\bjס5J#p@<   $% dY 5 #^Y^Y?+?+9/_^]^]]33+33933333333310#53!23##!3254#'32654&+PVծThyhvLJlBGrKUPEyX&@ ]Y ]Y ?+?+9310"327#"32&rJ\&E1'-HBJJ(@   ^Y^Y?+?+993310)! 4&+3 Ji#ž/JJJJ ~@R ]Y8i/o?O  ^Y ^Y?+?+9/_^]qr]]q3+393333310)#53! 4&+!!3 Jrr] &“t/ՓBJ Q@.   ^Y ]Y ]Y?+?+9/_^]^]]+933310)!!!!!Bn$AJϑV{X$c@:  %&^YXho ""dY"dY?+?+9/_^]q]]+99333310#"'532654!#532654&#"'632dudχOP²k\LaTBe4ΜA%/d\aSHR(=u{dJ'@  cY??]+93103##"&54632=-*??*-=J<77<;88^J "@  ]Y?/]+93210"'53253+FAF=6ՙ J 6@    ?3?3939333310!##3673 X* {?LXJ 5#+FJ L@,    @  ]Y?+?9/_^]993333103'737!=HJ`#wNH q{͖#J0@     ?33?3999333310!#33#47CBRZjJVNBJ,@   ?3?39999333310!##3&53B DWF;J iHkyZ (@  ]Y ^Y?+?+993310#"3232654&#"')  'HX&@  ]Y]Y?+?+9310"'732654&#"5>32ЎCprDaGB23)! &@ bY bY/+/+993310% 546$3 "3265oЊ -)~=?3+@   bY/+/993333104! '654&#"#&3#, 3?<O:8et%"Q@-   #$ bY bY /+/+99933333310% 547'76! '"6527qDsP -JsN`s3af/%sRw\vOyZ=1>Gm?}/Ekj#\+2t@C&0& /340^Y /?#]YaY),,]Y ?3+3?3++9/_^]^]+99933333310 >32#"&'#"=!!"5>4&#"326267!!?Јz>< \cPے| \psqpns m} ,%#ԟuJ#L@'  $% ""^Y^Y?+?39/+9993333331026=3#"&547&=3!2654! 3gnHSϘm~qhd+SݰΪRTƔgrzmy'Z @   ]Y ?+299104&#"#32۪' 'y' @   ^Y?+29910#"33265ᆲ') J :@  ^Y^Y?+?9/_^]+9933310+#! 32654&+i9X|w`J`i`^1J G@$   ^Y  ^Y ?+?39/_^]+9993333310 #.5463!##";9shHz~F*pQ]1JG@$ ^Y  ^Y ?+?39/_^]+9993333310#";3!"&54673Ӌ~zhs\Rp*E+J%@ ]Y?+3?9310!#!5!!7`J%@  ^Y?+?3993310#"&533265綂J==}~N`6@  bY  bY /+3/+993333310!2654&#!5!#!NJQY5w 3oN` ,j@8  $$**-. !'' bY   bY /+3/_^]+99//3_^]393333333310!2654&#!5!#!2#"&5462#"&546JRX56//642246//6422y 4m8('::'(88&'::'&8NB"v@D" "#$ bY "bY" "bY/?o /]]q+/_^]+9/+939933333333310!2654&#!5! 54&#!5!#!N‚JPZX`53lsᙌ /iN 4tJ @    ??2999103673## kJGdFVY)J"@   ?3?3399910!#&'#3673673Ӯվ ŰU4-`=Jh@YKVlG]@`VyJ 8@ ]Y]Y?+9?+993310)5!5!!y3By;yDJK@'  ^Y dY ]Y ?+?+99/+39333310!5!#"'532654&+5j 򄷽!ƟGVgdfZdFX#=@ $% ]Y!^Y!?+?+99993333104>7>54&#"'6323267#"&d?Z]]b7̅grqDV-JnW30RF?OBDu;8W@KS,&A!Z!.@  "# ]Y?3+3?99310327#"&'#"'53267.54632D,7?2U[X\YS6J9{J|sȢB\evsvs]ddHJ@]Y?+?99310!#HJLJJ @   ?3?99910!#&'#3$  j@TZLJJ%@ ]Y?+?3993310!#!#!bJJJmJ@@    ^Y ??339/+3393333310!##".53!3 3+ ij˔Dezquq|eJ)@ ]Y dY?+?+?99310!#! #"'532>7!2Gvi>=@**30IlwQ)@ 0IN?3?9/]39910!#3 &'%{ym  j114E S@/       N IN?3?33?9/39/]]q39333310!!#!!!!!!#pu012 O@   @I I N?3?29/]]+3993333310!2#!32654&+3254#5TPůpamw~Rr9RFPJ?`#c@   $%  @I#IN?3?39/]]+33333933333333310#53!23##!3254#'32654&+5PơMů箦pamw~aADhFPJ? @   IN?3?3993310)!24&+3 Luイ >@#  I N?3?39/]]q3933310!!!!!!^Jco <@"    I N?3?39/]]q3933310!!5!!5!!odJ`=Fq.@  JO?3?39/3933310!#"5432&#"327#\%;Eo5AAʹ >@"   IN?3?39/]]q399333310#!#3!3Ө!ߨ3\T 0@   I N?33?3393333310!57'5!kwwxx```D !@ @` I?]293210"'532653'=@G4<=JF% 8@     IN?3?3999333310##3>3R#k`Hy/+B@ IN?2?993103!0@    I N?33?3999333310 #3 3#47h+1\AmQF ,@    IN?3?39999333310##3&53blZo= ,@    I N?3?2999933331033#47#ӅT'EqB  @  JO?3?3993310#"543232654&#"Bߡm$A@ ! !!%& ##IO?3?39/39993333331026=3#"&547.=33254#"_hBNZiùEFfZj_](#jM&XahT 0@  NI?3?9/]39933310+#! 32654&+T`!Rr|n{VeXX8@    N I?3?39/3999333331032654&+#!2#Lpgnq}-ǼWWYK)hL='H @ NI?33?9310#!5!! !o @ I O?3?3993310#"&533265ըt~sȳs}u%^"@   IN?3?3399910#&'#3673?3Hؠ겞  R-&,"lTB^6bJ(Z#A@#! $%   NLO?3?3?9/]q399333310'#"&54%754&#"'632%26=j.q[{oIC7t61`m\yoBV4.zm VB)uH}qi^3BG62#=@ !!$% / KOL?3??9/]]399933310>323267#"&5"7>54&3sTzoIB8r81s`mZzpBT7+|m UB(wG|oj^4AG64h30@    K NLO?2?3??99933310"&5463273#''26=4&#"`)l326324&#"7>27!l]38HH&uJEvAAvI`+`y>3YeVpi}L !At *w8?X  RJxp65j]3AVb^0@   F NLO?3?2??9999333102#"'#3>"324&T}/f6f]_hZͿsg5U<;:vxh34@     FNLO?2?3??999333310"&54632&53#''2=4&#"Ni) 6k0`hVa\л=8MHi@55}hB@&   / LO?2?39/]]]]q39933310"&54632!3267"!.qgE{HuN\ [OзݿXpu 3aXTeb:@     ,   LO?3?29/]q3993333102#"&=!.#"5627!¢rgtpWиۼVqt=6bX`X ]@9 !"       /   L O?3?39/]]]]]]qq399333310#"327#"&547.54632&#"39{¶ulBUIQ>tkqnH7zi1W?ar%{8[bH]@9  ! /  LO?3?39/]]]]]]qq399333310254#"'632#"'53254+5;ǚ;g?9l{b[{qGJP%50=@ KN L?333?33?9993333104#"#4#"#3>32632\eU^Y .lAAVxpZxrrG8h=2@KN LM?2?3??9933310"'53254#"#3632^9@A(Lkb blhgNwpjwmhP  @  LO?3?3993310#"&54632324&#"PǰŰchcjef7պֶ}F @  LO?3?3993310632#"'732#"VV}c1*c%bs0ӿ/ 5h5P @   L?3299104&#"#4632he˨Ư5ضhP5 @   O?329910323#"&5ͨƱ5Թh^0@    K MLO?3?2??9999333102#"&'#3>"32654&Mj(1n2`i[]]ξ=8HNNh=8~~1#`.@    KO?3?399333310267#"&5#5?33#MT&|umq3m6%z zxN3{c>;5)@    K NO?3??39993331032653#'#"&51HLka -yDTPzq9DXf*@    /33/399333310!2654&#!5!#!XSPyoq9D HKkb -yD9@  !KN O?333??339993333103265332653#'#"'#"&5/dW_Y .lAC)KwpwqG6DC @  KN?2?39910 3673=կ@>n]O!(@"#L O?333?99310327#".'#"'532>7&54632uYMJT2,$E;HI'9nOF%1)&.5utECd w80B?y,$sh$?@" ""%& MG O?3?2?9/399333333102#"'#46"3254&+532654&sjhixk^P\fc򒅷2/ꔝ5>3bcXTNNh@   KM??399910#4673673'!Ŭ-&!%h:`qrFHlVfN)8@ $*+! F'O?3?393393333310467.54632&#"#"&%4&'326fSK~K^Hq50Coǰ@VLx|mZdkt,3hEbl#,}M-"*D:QrXn&eYirhh <@  !"LML O?333?3??933333310.54746324&#">״9B˄rЯJ9Tdsh@ϯϽVF^"ҫ}qhH /@!"KMK M?3?2??999331023327#"&/#.#"56-<.%P˰0$$0/>Yj,TLs)"/:ZtG0 yRq`F!37y`By,@  RP??]2933310#3'4632#"&76($77$(61--1---`yo%@  R PS?2??99933102&#"#3>2?31Vu/co efcKU5c P?5ac P?5  Q?55cR?5No8@  0    SQ?3?3]q99333310%#"'#4632%"32654&NnS`[HpeZY/8dսS;hr Q?55HeR?5^%,g@8# ** -.)^Y)))) &]YaY^Y?+?+?+?39/_^]_]+999333310"&'#"&5332653632!3267"!.oH4約}uXmX /^j_c=}sm-&!ߦ{,9@K 77*:;$!&)// @&/ ""-]Y4]Y?+?+??999/_^]3^]q]232999993333210"'3632#"&'##&#"#>325332673"32654& oo7!++ i eU)+f f qqPOx ;32533267326=4&#"hsw  #++ i eU*+f fX( .y;32#5754632&#"!!32673 ++ h dUil0]F[X**f h L;?%xG;<~^+4=@V'?5  ,7#++. >? 7,#.&55/555@*.@   1;;]Y?3+3?33?9/_^]333]2299933333333332310!"%#$'##>733>3 3>32>735#"%54&#"#-/i`] /jN 5t2+ g aaFBߙICmt+B* .2`xǖPZX`Ӟ 5,azZP):-[^ +~@H- ! %,-?!!!!@ H! !%%@ )]Y?+?3?99/_^]333/+]q33339933333332310!&'&'##>733>32>7354&#"a]Z ic\ 3o0.g]`w)) cpxQYϦ:5&d &+ {^,9@, 1$ 77*:;$&)/ @& @ H -]Y4]Y?+?+??999/+33_^]]22999993333210"'#5&#"#>3233>32#"'#32673"32654&#++ i eU @nw *+f f ;3233>32&#"32673++ i eU $?eI8=:WT*+f fj  ;3254632.#"32673#"' ++ i eUR^N8HG!*+f fT;3#5?3!!32673#[Q#^i6,* h eU"Hk=$**g dr_f S;32!5!32673AeT0-++ h dUCo*&**g d)w;323##"'###267!"!.@nb\ w VZP)N==ȵɴFJc@5     ^Y5^Y?+?39/_^]^]]33+339933333333103##"&=#533!26=!璒JCwsC9~ww}J!*|@G(!'((&+,'^Y5 ]Y "]Y ?+?+99/_^]^]]33+33933333333103##".=#5367!5!!.'5!26=!/o[]o)L|[zJӚ}z y"slͿ j{ -P@,++./ !]Y (]Y aY#?+?+?+??99333310"'532=#"&'##33632"32654&.8cmil0]F[X[jkT>?%xGo ^)6l@:#4-) )78  ^Y 1]Y *]YaY#!&]Y!?+?+?+?+?9/+9993333333310%7##"32373!#"'532=!#"'53265%26=4&#"oy 3 3>323?;?.8bjߙmt /jN 5tZjkÂJPZX`j^ N@)   !"  ]Y ]Y aY#?+?+?+??993333310"'532=#4&#"#33>32332#"'532="32654&w @nI8=:WTZ/TkEXXJAZ:H7k!Yl\V!YkjJ?@    ^YaY#?+?+?399333231033>73!#"'532=!E D.8b1bekJPjsJE@%  dY  dY aY#?+?+9?+9933310#"'532=!5!5!!s32332726=wus;#R|lwWD7S`Z65.0*ijgINA}w4 ,2H;cjrV\qj`^*W@.,( ! +, %]Y ]Y]Y]Y#?+?+?+?+?99933333310"323733327#"5#'#'26=4&#"3w[551-*YJsƤ( .LH;!q 5W@.++7 /%33/674 !aY]Y ]Y -(]Y-?+?+?+?+999333333310%26=4&#""323.=32&#"327#"5467#Psw  H?/;/2-8@&*e  v!ҕ*  .y6AapU!Vwqj^%Y@1'  ##&'" ^Y""""]YaY]Y#?+?+?+9/_^]_]+9333310"32!3267327#"5"!.Xj651-*YZ/+9m-H;ߦXj\^0z@D2( .." "1200]YE0000000%%,]Y%]Y]Y#?+?+?+9/_^]^]]]+993333333310# 3267327#"5#"&54675.54632.#"!וʔUd651-*YZsqcjoWDcJ9Y]'/H;c& ]%),Dj^.w@C#-# ))#/0-..-]YE....... ]Y &]Y!]Y!#?+?+?+9/_^]^]]]+99333333310 54#"'632#"'327#"32654&+57O_?}vu`651-*Y緽(L8$g}H;VV^\^[hju^!(o@B *&%)*&&^Y /?OaY"]Y ]Y #?+?+?+9/_^]q^]3+39333331023327#"#"=!.#"5>267!65.0*YXj[^9H;5 m-' !jG@(  cY` ]Y ]Y #?+?+?_^]]+933310%3327#"5#34632#"&bZ651-*Ym=-*??*-=H;J)<66<;88Djf^"6@ ""#$aYaY ]Y #?+?+?+933310732654&#"'>32#"'327#"V7271^H*64/0*Z@"sH;jL :@" !"]Y^Y ]Y #?+?+?+93323310327#"3265!2.#"b~~651-*Y19H7\4>H7BmH;YlV!YkjfJ!I@&#   "#! ]Y]Y]Y#?+?+?+?3993333310326533327#"5#'##"&5Xw}Z641-*YL 1wJ="32654&\(l=h_`i[[[мuih8=t~~h @  LO?2?3993310"&54632&#"327ױ·6($77$(6nlrTLYS2?:1--1-..h @   FM?3?93310327#"&57X%P?F|ruwyzzh3 @   F M?3?93210#"'532653szF?N&/)szzy<;@ KN?3?993103!!Zh'D@"  ()  KN $ LM?3?333?3?9993333310#"'53254#"#4#"#3>326326:>/eU^Y .lAAV7AqxpZxrrG8h <@ !" KM O?333??339993333103265332653#47#"'#"&5/dW_Y .lACXwpw:E>G6h;2@    KNLM?3?3??999333210#"'532653>3 #4#"7B4< & &Rjc\{4CXt=Dyh4@  KNL M?3?3??9993333103267#"54#"#3632;);C"̖jc e^?8 { Byrp}L ,@    KN?3?39999333310##3&5Lh)9`f'_@3    / K NO?3??39/]]33333993333333310!33##'#"&=#53267!1`mm -yDdd:faH'}q9DQ}'qlGTPDs:@     ! KO?3?39933333310#"&5467#5!32654&'5!KQǰRJjIUhcbk]Em5-Y³q7t mozzqet9 @   K O?3?39933102653#"&53\WW'ixNRxi9%@ KLO?3?3?933104&#"5632#"&533265",43B;ufPbaRB.v|ͰRvkhy @    N K??399910 #&'#--WU\PAR .@ KN?39?3999333310!5!5!!4v`'{lRhH9@ KN M?3?39?3993333310!5!5!!3267#"&5D4v&A 4Ec^`'{lC4{x|R55e@;    /  K N?3339?399/]q3]]933333310'?#5!5!3>32#7"32654&6x4vREZMc8?8E5,1*$`'{l\XCb!-h:@ MK?39?39/3393333310#"'532654&+5!5!ٴp54.54>54#"'632Z!(!!(!#+#2,.C6h & $$ZN?  7=   q@   /]3]210"#"&=332>;dNwp:n|k*cxWT%-%nmu#+#7@/_/]210!7!%Ej/@/_/]310!%7!/E%ٚ7 /2310!'!JEߙ/ /3310!'%!/EJNB/@ fviy_/]2/]33]]10%7%'E(EÛB/@ fviy_/]3/]33]]10'%7E(EHZ  H/+2/102&#"#36d'%&JCyiABn Y[PZTR @ /?/]10&'5673_x-uHmgiG:,g#@  0O_/]]2910#.'537673%#567&'5 NRh*=*#hd/_'nO=[T2:&('N Rz{@ &% %+5+5+5q&H&Nzo@)/*%' %+5+57&)O\R@ & %+5+5`&IO{@  %&+5+5};&*MR@&w%+5+]5q=j&JM ,+%+5%7&+OR@ &  %+5+5L7&KOR@ 8 % &+5+5%&+dZ   %+5L&Kd %+5%)&+jR@ !&  %+55+55L+&KjdT@ 8) %,&+55+55Z%&+z= %+5>L&Kz! %& %+5%&+N"   @ H  %+5+]q5L&KN$ H" %+5+]q5&,R%@ @H@ H! %+5++q5&LR'@ @H H% %+5++q5)wJ&,JR&@ 0@&( %+555+q555D&@  %+555s&.vR@ &%+5+53&Nv{{@ k %&+5+5&.dδ %+53&NdѴ %+5&.Mq@  p  %+5]53&NM@  p %+5]5&/d %+5s&Odm  %+5&/'MRd)@  &@ % %+5+5+]5:&O'Mdm'@_o@H&%%+5+5++q5&/M@  p %+5]58&OM@ p%+5]5g&/K! H# %+5?+]5gc&OK@ H# %+5?+]5{7&0OR@ & %+5+5&PO#)"%+5{&0d %+5^&Pd!#)"%+5N7&1OR& %+5+5L&QO  %+5N&1do  %+5L^&Qd %+5N&1M@  p %+5]5L^&QM@  p %+5]5gN&1K!!@ H!#! %+5?+]5gL^&QK!"" H"#" %+5?+]5}^&2 HR"H&!-%+55++55qh &R Hj!-%+55}&2 FR$0@H0&9E%+555++555qh&R Fj9E%+555}^&2 IR)@P` @H&%+55++qr55qh &R Ij%+55}^&2 JR)@P` @H&%+55++qr55qh &R Jj%+55os&3vXR@ &%+5+5{!&Sv =+' %+5o7&3ObR&Ѵ%+5+5{&SO"( %+57&5OsR& %+5+5/&UO %+5&5d %+5/^&Udm  %+5&5'M!Rd+@& % %+5+5+]5/j&U&Mdm % %+5+5&5MJ@  pԴ %+5]5/^&UM@ p %+5]5h7&6O=R@ /&&,%+5+5hy&VO$*%+5h&6d&,%+5hy^&Vd9$*%+5hs&6 CVR@ ;&N&7%+55+55hy!&V C "$5%+55h&6 DFR@ <&>9%+55+55hy&V D  <7%+55h7&6'O=Rd/&@ 28%&,%+5+5+5hy&V'Od9@ 06%$*%+5+5\7&7O/R@ &%+5+5!&WO+@0 O   %+5q5\&7d %+5!F&Wd/  %+5\&7M@ p %+5]5!F&WM]@ p %+5]5g\&7K@ H#%+5?+]5!g F&WKQ!$$ H$# %+5?+]5&8j#@/?P$%+55]q55DJ&Xj&@/?P' %+55]q55&8Rs'@ /@ H'%+5+qq5DJ&XR)@ /!!!!! H!* %+5+qq5g&8K@ H#%+5?+]5gDJ&XK!"" H"#" %+5?+]5^&8 HR @H&'%+55++55D &X Hy * %+55&8 ER1@!P-`- ----@H-&-,%+555++]qr555D&X Ew@ 0/ %+5553&9RR@  & %+5+5&YR # %+5&9d  %+5J&Ydm  %+5V7&:OR@ "& %+5+53&ZO  & %+5V&:d  %+53J&Zd  & %+57&;ONR@ & %+5+5%&[O   %+5)&;jR!& %+55+55%&[j   %+557&<O9R& %+5+5&\O %+5NDs&=KR@ & %+5+5Ps!&]K  %+5ND&=d   %+5PsJ&]dF   %+5ND&=M@ p    %+5]5PsJ&]M@ p    %+5]5L&KM@  p %+5]5!&Wjߴ) %+553&ZP & %+55&\P  %+55^J&D ,)%+5`&AO{@ &  %+5+5d"L@( " #$"kY  iY kY?+?+?9/+393333310 .#"#4! #"'53265!#?&w&~lU\9POSŴNO.2 q1&~s  -3%+5q1&~Hߴ6-%+5q1&~5-%+55q1&~۴>-%+55q1&~ "-@%+55q1&~ 6@%+55q&~ 6B%+55q&~6B%+55&$v%+5?5&$Њt%+5?5'$%%+55?55'$"~%%+55?55'$!%%+55?55'$!%%+55?55|'$"@o##%+55]55|'$"@o##%+55]55X1&) 30,%+5X1& /,%+5X1& *8-%+55X1&  7-%+55X1& W09%+55X1& B/9%+55'(p %+5?5'(c %+5?5'(Ŵ #%+55?55'(  #%+55?55'( #%+55?55'(ݴ#%+55?55L1& 9 %+5L1&  %+5L1&'' %+55L1&B& %+55L1&7 9( %+55L1&% '( %+55L&B $* %+55L&B $* %+55'+p %+5?5'+c %+5?5'+Ŵ #%+55?55'+  #%+55?55'+ٴ #%+55?55'+Ҵ#%+55?55|'+"@ o   !!%+55]55|'+@ o    !!%+55]551& %+51&%+51& %+551& !%+5581& U#%+551& %#%+55& (-%+55&0(%+55R',p%+5?5E',c %+5?5d',#%+55?55Z',  #%+55?55',5ܴ #%+55?55',5մ#%+55?55|',=@ o   !!%+55]55|',=@ o   !!%+55]55qh1&Rh"%+5qh1&R\!%+5qh1&R*%+55qh1&R3)%+55qh1&R )"+%+55qh1&R !+%+558&2up%+5?5J'2c$д%+5?5}'2#%+55?55s'2,%+55?556'2st--%+55?556'2s$t--%+55?55y1&{%+5y1&d%+5y1&#'%+55y1&;&%+55y1& (%+55y1& (%+55y&3 *%+55y&*%+55'<5c %+5?5'<?~%+55?55'<T۴%+55?55|'<@ o   %+55]55s1& 2. %+5s1& 1. %+5s1&:/ %+55s1& 9/ %+55s1& )2; %+55s1& 1; %+55s& 1= %+55s& 1= %+55k&vup#&& %+5?5'vc, %+5?5'v+'' %+55?55'v4'' %+55?55s'v}#d55 %+55?55}'v,Z55 %+55?55g|'vq"@ o   == %+55]55g|'vq"@ o   88 %+55]55q&~0-%+5q&~ 41%+5X&)&%+5X& 6-*%+5L&+Ҵ %+5L&H D %+5D&Ӵ%+5& /%+5qh&R˴%+5qh&R% 2%+5y&%+5y&- %+5s&Ҵ,/ %+5s& -/, %+5q=1&~'s @ I<% -3%+5+5q=1&~'H I<%6-%+5+5q=1&~& QD%5-%+55+5q=1&~& QD%۴>-%+55+5q=1&~&  @ QD%"-@%+55+5q=1&~& @ QD%6@%+55+5q=&~& @ _R%6B%+55+5q=&~& ^Q%6B%+55+5&&$@ ,.%%+55+5?5&Њ&$ @ ,.% %+55+5?5''$! @ 4%6%%+55+5?55''$#4%6%%+55+5?55c''$!@ 4%6%%+55+5?55c''$! @ 4%6%%+55+5?55k|''$+@ o@ B3,D%@**%+55+5]55k|''$+@ o@ A2+C%@))%+55+5]55L1&'@1$ %@ %+5+5L1&'@1$ %  %+5+5L1&&'@9, % %+55+5L1&&B@ 9, %& %+55+5L1&&7@9, %@( %+55+5L1&&%@9, %'( %+55+5L&&B@G: %$* %+55+5L&&B@F9 %$* %+55+5 @'+'p@ *,%j%+5+5?5 3'+'c@ *,%g %+5+5?5 q'+'!@ 2#4%z %+55+5?55 g'+'!@  2#4%z %+55+5?55 R'+'!@ 2#4%%+55+5?55 R'+'!@ 2#4%%+55+5?55 y|'+'*@ o   @1B%!!%+55+5]55 e|'+''@ o   ?0A% !!%+55+5]55s=1&'@ D7%(. %+5+5s=1&'D7%1( %+5+5s=1&'@ L?%0( %+55+5s=1&'L?%9( %+55+5s=1&'@ L?%0(; %+55+5s=1&'@ L?%1; %+55+5s=&'ZM%1= %+55+5s=&'YL%1= %+55+5 V&vu'p#ߵ=0@%&& %+5+5?5 s'v'c,ߵ>/@% %+5+5?5 'v'#+F7H%'' %+55+5?55 'v'#4F7H% %+55+5?55 ^'v}'##߶F7H%d55 %+55+5?55 i'v'!,@ F7H%%33 %+55+5?55 R|'vq'-@  o   ߶TEV%== %+55+5]55 R|'vq'-@  o   ߶SDU%88 %+55+5]55q&~N08%+5qj&~M-.%+5q=&~& B5%0-%+5+5q=^&~ :-%+5q=&~& @ B5%41%+5+5q&~R6B%+5q=&~&R RE%6B%+5+5>&$N/R@ %&+5+5&$MBR@%&+]5+5&$%+5?5&$Y(%+5?5&$%+5s1:@   0@ "H _  /]+]q293104632565"&=-27jxy-=4.D5mz K U.= -@  `Y `    /]/]+93310327#"&=$,6GJXo-) w^eYs?5R#/]@;*$$ 01  @ H  /@H'-! !!!/]q]3333/+]q2/+]3393310".#"#>32326734632#"&%4632#"&+SNI"21^ ja-UNG /2\ m8('::'(88&'::'&8$6.l}$6.qx6..651156..6511L&&+* %Ѵ %+5+5L^& " %+5L&&H@* %D %+5+5L&R * %+5L&&R@:- %* %+5+5'(:y%+5?5'(%+5?5'+:y %+5?5'+%+5?5&+  %+5?b14@ o_/]]]29310#&'53%4632565"&bVED=-27jxy-=٥j4.D5mz K U.h14@    o_/]]]293104632565"&673#w=-27jxy-=DP{V4.D5mz K U.j$F@.## %&  @ H   / _   /]2/+]339310".#"#>32326734632565"+SNI"21^ ja-UNG /2\ m64iqqyj$6.l}$6.qxs*.j]] D6&N %+5j&M %+59&@ *%+5559&@ *%+555&R %%+5&@ %%+555>&,NR@  & %+5+5,&,MR@& %+5+]5/',:s%+5?5T',%+5?5+D14@  o_/]]]29310#&'53%#.54632DVC>>-ywj71->٩2.U K zm5D.h14@   o_/]]]29310#.54632673#;=-yxj72-=:DP{V2.U K zm5D.j#F@.  $%  @ H  "/_/]2/+]339310".#"#>3232673#.5432+SNI"21^ ja-UNG /2\ mjyrohj$6.l}$6.qxsV6D ^\jy&N+ %+5yj&M-%+5y9&%/%+555y9&%/%+555f1& '# %+5f1&\&# %+5y&R*%+5y&*%+555>&<NR@  & %+5+5&<MR@  & %+5+]5'<):i%+5?5'<% ɴ %+5?5'3c]%+5?59;@!   ! o /]q]]22393310#.'53%4632#"&%432#"&V?q@H6(&88&(6_%92,*5N7{@6./55225d/5-:29;@!   ! o /]q]]22393310673#'4632#"&%432#"&:#q=V6(&88&(6_%92,*5 ;KX6./55225d/5-:2$@ o_/]]]9910#&'53VCD٩js=&'=0%Ѵ+( %+5+5s=J&5(%+5s=&'@ =0%-/, %+5+5s&R 1= %+5s=&'RM@%1= %+5+5R'2:%+5?5&2D@ -%+5?5'v:%ܴ %+5?5:&vD@ "'$$ %+5?5N&vB/ 1%+5 $@ o_/]]]9910673#>CV1:@   0   @ "H _/]+]q29310#.54632q>-yxi71->2.U K zm5D.+//10#+V!@   //310#'7'77'+V5555X7777  //339210'7##!'77RJ75}o}7L)  //339210##'7!)T77L}57}RB'/399105!R `'_ _@   ?32910#&'7##&'7`$C-j$C6e ^mrY /3/10#!+ToPN) /3/105!#NTP@  //]210###!V @   /33//]3310###!!!VtP @    /3/]2210!!5!###tVPN6& q #/@2 $*01* H}Y '%@? H!}YP!`!`!!!!O! !! '*---- H'-}Y'%@ H }Y ?++_^]_]?++_^]_]9/^]]q++_^]_]9/++_^]_]99331074632#"&4632#"&4632#"&4632#"&@?=BD;=B@?=BD;=BA>=BD;=B@?=BD;=BoBIHCCIJyBIHCBIJDHHDBIJyBIHCCIJ!@  /33/]23103#5!#3###VPPN @  /3/]2210!!!##32#"&2654&#")J17L oU{FN`USOpiy+;^\^NXUeX`RN\V9`mZUn Q?55hUp Q?55hUPp Q?55'`#b 4@     R P?3?39993333310%33 # #Fﻶź{ybUp Q?55JF@R  !mY*:  mY mY mY?+?+9/_^]+9/_^]]q^]qq+33933333310)#"5432&#";!!!!!F'ɟ~BofzVq@:ϲdh"*0@I .&+ +&- (!!)(- 12-( kY .##kY"O_/3/]q3+33/3+33/39333333333333310&'27##7&'#&4?37327"& )FAG;%DžQj%'YG/<'#H.%-'DX)Zx -9! %~S4R,́9sL&M@(% " "'(% #kYkY"  kY?+3?+9/+99333102&#">7# !2.#"36;>B+]~J_Vb@٦J;b~ _ l #l\V13qT'_@4 &&() &$ $]Y@'''$?3/?33/]+3?993333333310632##"##54&#"#33>325R^ߙmt /jUT!5uJPZ!%*/@g- )$*("(&$ #  !,++,#$01" -mY ( %mY/*/ ?3?39/]q+9_^]+9933333333333333333105#533333#3#####5%#3!3'#3''# 4񢠠)== VZ VG{e{߿ X <t@=/  )6)"")=>%")96,3^Y, kY kY ^Y?+?+?39/+3?+99933333333310#!2#'32654&+#"'53254&'.54632.#"X+nk!s|^59Gol^.W;B9e9GNIqj^.\Џ2q\~A%1=R@7#iXP^aLTe{Vb\\<;wr "X-I"H wcVXL@*    mY/   ?3?39/]3+3393333310!!####53333V)s53T}'oq@@       @ iY?+3?99//_^]99933333331077#'%5'%!5!!IIǸJ:J:7H9ťlϦmFPṃl1y9_@6#0 0*+(7:;))(lY( 3kY(+kY(lY?+?+?+?9/_^]+9/93310#"&'##>32%"32654&2+332$54$#"'>ye|5eH%əSj(ocJT4!VJ>Lol)^~% htjXrHRz@&"%-!"+Z@/ '#,-*   %lY  lY ?+?+??39/2999333333310#"'532654 #&546324#"6vlcHRRH=P~&PUqu;.}j!YWf-9xR_!&,@*#",   # -.nY" P +nY/   ,kY? O _      &kY?+?9/_^]]q+9/_^]33+33_^]qr_]22+339333333333310#3#+##535#53! 34'!!6%!&+267!7r?U-'J׏hy*V%J'Eo#on#))=VAJ}\;!i@9   "#iY @ H  iY kY?+33?+333/+9/+93333333105$%53&'!67R-FBvS?"OGRO3C + "{@C    #$ mY  mY  ?3?9/33+33_^]22+339933333333210!!3##!##537!5!3!'!73'&'8=˜ªî<4;-I"P僨#υOP0@O.&//, ..,12mY 0/0/mY00?0O0o00000) iY)#iY)?+?+9/_^]3+3_^]2+393333333310>7!5!654&#"'6323#!!327#"$547#59z6:kZ3?E{c/L-9_epNRʫXBV?9^n~a"-ܿFA}\N@*   iY @ H  iY?3+3?33/++39333333105$%53&'67BԛJܤU@MG LFf56x@B   mY mY  mY?+3?9/_^]]+99/3+3933333333310!.+5!!!!#53267!-P}b}- sZrgN1{Zdu"` dD"2]@7# ++ 34       p  /'?3?39/]39/]9/q3933333103254&+#!2#%4$32#"$732$54$#"吪SY/^^m+*լ֭ۢQIE^ZƬ֭+*  26u@E&  5- 3 5 7865 E   p 0 - * #P#@###?33/]q399?33/]39/]]]3??93333310'##3/#"&'53254.'.54632.#"#HIEF>t%'3??i\w;y+#&i-968\qZݕ"@3CF[i}N"!#$_P[hm)+-&aJ=J .@  ]Y]Y?+?9/+933103!5!!5!nCJ_.'`&{u?51-'&tu$?5FX&@]Y ]Y ?+?+9310"'632#"&'532654&pE'bDrBH1d^D 1@  p /3/]/93310#&'5673!9>HH>9)DH$HDV @   //293105673&'#DH$HDV:=HH=:#d^D 1@    p     /3//]93310&'3#67!59>HH>9#DH$HDV @    //29310%67#&'53+DH$HDV9>HH>9d^D?@%  p /3/3/]39333310#&'5673!&'3#679>HH>99>HH>9)DH$HDDH$HD(@   /2/29333105673&'67#&'5DH$HDDH$HD:=HH=:9>HH>9H0@   /2/2293333310!!5673&'67#&'5 DH$HDDH$HDhPX:=HH=:9>HH>9yH^y`@ //3993103!!^j8^@   /3/29933104>32#4&#"rуwfŠdHP @@&  P_ / ? o  /]3/]3/]3993333105!5!5!d8d7 @  /3/29933103 %! {RVj-Gn@#@  /3/99310#4632#"'&'&#"}?L3% &!" @/)3 )''#i@  //3993103#"&546323265#9P3## #>/'5)%37/333105! h//93103#בK7@ /2/93310!!#'k7n7@ /3/932105!# )@ //3933103!!n@ //3932105!3  @   ///39333103!!#knn@  ///39332105!3# K7@   /32/9323105!!# kn@   //339323105!3! n (@    ///332933323105!3!!# knn6@ _/]]3_]q/_]33333105!5! BZ@  /2/39933103#3#ّiK K >@!  _ /]]2_]q//_]39333310!!!!#'kkב"7 &@   /33/39933310!###ؑ7nn# B@#   _ /]]2_]q/3/_]399333310!!#!!#iro" :@ _/]]3_]q//_]393323105!5!5!# i)ג(7 "@ /32/399332105!### ݑؑn @@"  _  /]]3_]q/3/_]399332310#!5#!5!ӑtt(F(ޑ <@    _//]3/]]3_]q93333103!!!!k#ב $@   /3/3399333103!!33B%n#n @@"      _/2/]3/]]3_]q993333103!!3!!ّJ%i# 8@  _//]3/]]3_]q93323105!5!5!3 iג) "@ /3/339933210!5!333#ؑn >@!        _/3/]3/]]3_]q99332310!5!3!3!5!#LF B@#  _ ///]]3_]q/_]3933333103!!!!#kk#ב" *@    /3/3/3993333103!!#3#Bnn K L@(   _    /3/3/]]3_]q/_]39933333310#3!!#3!!jr " # >@!  _ ///]]3_]q/_]3933323105!5!5!3# iגK &@   /3/3/3993332105!3#3# 㑑iK#K J@'    _ /3/3/]]3_]q/_]399333323103#3!5!#!5!B㑑tK (ޑ B@#   _   /]]3_]q//_]32932333105!!#5! ki"h7 (@    /322/3993323105!!### ؑnn N@)    _ /]]3_]q/3/_]3339933233310#!5!3!!#!5jtrrBޑ"ؒ @@"  _  //]3/]]33_]q932333105!3!5! BZ# (@   /3/333993323105!333! ؑnn L@(         _  /3/]3/]]33_]q399332333103!!3!5!5!B#oV@-   _  ///]]33_]q3/_]3329333332333105!5!5!3!!!!# ikkג#ב">@      /3/3/333339933333323103!!###!5!33Bؑnnnn d@4  _  /3/3/]]33_]q3/_]333993333332333103!!#!5!3!!#3!5!Bؑtr#ޑ" //3310!!V//3310!!V//3310!!V //9210!!+ //9310!!+ *fw% #'+/37;?CGKOSW[_cgkosw{@"2Jjj#3Kk.FVznn/GW{o6Nff7Og*BZ~rr+C[s :Rbb ;Sc&>^vv'?_wwcsgokcgkk`dh_[WW\XTOSKKLPHC?GG@n?o*Z+[BrCs.^/_FvGwA#&.6>JFF'/7?KG"*2:NBB#+3;OCCG@ PQӸCи@ԯ?<;87{{|4xgkosw3ccdhlpt0`OSW[_/KKLPTX\,H7;?CG+3348<@D(0#'+/' $(,$ #  KH@Ԩx`H00H`x DAGO   L/333/3339//////////33333333333333333333333333333393333333333333333333333333333333333333332333103#73#73#73#73#73#3#73#73#73#73#73#3#73#73#73#73#73#3#73#73#73#73#73#3#73#73#73#73#73#3#%3#73#73#73#%3#3#'3#'3#'3#'3#'3#3#73#73#73#73#73#3#'3#'3#'3#'3#'3#3#73#73#73#73#73#3#73#73#73#73#73#3#73#73#73#73#73#3#3#3#3#3#3#3#3#3#3#3#3#fiiiiiihhffffffffffhhiiiiZiiiiiihhffffffffffhhiiiiZiiiiiihhffffffffhhiiiiffffffhhiiiiiifffffffhhiiiiiffffhhiiiiiifffffffhhiiiiffffffhhiiiiZiiiiiihhffffffiiiiffiiiiffiiiiffiiiiffiiiiiiffbbbbbbbbbbbc^^^^^^^^^^^````````````e^^^^^^^^^^^`aaaaaaaaaaad^^^^^^^^^^^`cccccccccccb\\\\\\\\\\\bccccccccccc^```````````bbbbbbbbbbb%```````````bc^``e^`ad^`cb\bc^`b%`C%IMQUY]aeimquy}  !%)-159=AEIMQAS@zKk h| OoLldi}SsPp`"eWwTt\&a# +P;;Xxؿ)H*99]'A!/L?? ,Q<%D.55 &I+648<@DHH0M@26:>BFFA "E/22@6<@ ؾ RS@  $(,0ֹ:>Gʽɹ59ȹ48+/D*.C%)$( !@ ?| {~ osw <knrv ;jj\`dh[_cg@OSW8KNRV7JJDHCGLP@4 kKKk  ׹;?HKO@ 3"&*./333/339//////////333333333333333333333333333333293333333333333333333333333333333333333332333310!35#35#35#35#35#353353353353353353353#3#3#3#3#3#335335335335#3'#3'#3'#335335335335#373533533535!355#%355##5##5##5#353353353355##5##5##5#35335335335#3'#3'#3'#3#3'#3'#3'#335335#3'#335335#3735355#5##5#353355##5#35335#3'#3#3'#3+jjjjjjjjjjjkjkjkjmkjkjjkkkkkkkkkkkkkkjkjkjmkkkjjjjjjkjkjkjmjjkjkjmkk?kkmkkmjkjkjkkjkjkjmkkmjkjkjkkjkjkjmkkkjjjjjjmmkkkkkkjkjjjjkkjkjjkkjjWjjjjkjjkjjjjkjjkjjjjkkjjjjj!c c"a c!b!`````````````b^^^\`h^^^^^^^^cccccccb^^^^^^^^aaaaaaaa^^^^^^^^^^ccccccccb\\\\\\\\cccccccc^````````bbbbbbb bbbbbbb^^^^cccb^^^^aaaa^^^^^ccccb\\\\cccc^````bbb bbb{Z//9910!!{!!@  /2/3993310!!!7L17}1mh{//9910!!hmh{@  /3/3993310!!!hKPb//3310!!L//9910! XVRZ//910 7L//9910 LRZ//9910Z79e-)@  ! /3/39933104>32#".732>54.#"wx{yy{xwV`bcb`c``dyyyyxyy{b``bcbbbV^R'/7?GOW_gow@X\PhhTl8xx<|(pp,t ``$dHH L@@D0044DLdt|l\ JrvNvvvBz~F~~~2jn6nnZ^^RVVVVV:>>> *..v~n^V>..>V^n~v&f0b@bb"0p&/&?&&&/]]/]9///////32]32]3232q32]32]3293333333333333333333333310#"5432'#"5432#"5432#"5432#"5432#"5432#"5432#"5432#"5432#"5432#"5432#"5432#"5432%#"5432#"5432'#"5432377349947575#3773865567557R75577667377349944976#58856556\677675577667667+557775555885Z557w55763:C558337775555776557737+558#  //99102#"54>jmsoujlw)@  //9933103!32>54.#")wvuwwwvu}Bwwwutww)#'@ $%  //933103!4>32#".'32>54.#")R`babbab`Nwvuwwwvu}B`bb`c``cwwwutwwsbu &@   /33/]3993310#"&546324&#"326bcfdiFIKgFEgcIN_}khfJHfFffFHdhy $0:k@%+ 6+:;<51@) H168833@ H(.""O"_"3"3"  /  /]3/399//]333+3]+29333310#"'4! 4#"32#"&54632#"&54632327#"'ybbZٗ31Z-!!--!!-+!!//!!+LL=`bHgj34V// -- // --# #-S@4( $./)--!O_-&+++@ H++  /  /]/99//+]]]32]3910#"'4! 4&#"326%4&#"326327'#"'bc0!--!0.!//!.bb>KLHgj{ -- // -- //ۺ#Fs;)5p@=3$-%-"') 3 3 67"   $'0*()/3/39/3933333333333333310373#'#5&''7&'#5367'767"32654&BAe;-VL12WXByd+N P)opÉ;'--qt>}`+%* J-d}>^1N =LJŇP'$T@+  ""%& /@/3/]99//]333339333333310.54632!!#!5!"327654&qqwTVhL%Xw{TV;>wBh}VTylFFxUVy>=TVwR,8F@#0',!66,'9:,*3$-$*/3/399/99933333310&'&54763327632".'#"&54632"32654&+ !C=#"&5467>!aFXdP{XZ[Xe`Ga^%%`]ZRw;3C@&'. 45*   .#  //99//]99233]3910)7>5'#"&54672&'&5463267632#".'Fw^69Zs\=e% qtET'iCJt8v_=1op#8wL/yuzs3B'$'ykVb'NKuu2Qi}x6fZy@   /3/99910./.54632>32bZ[K6dV'!XaXoV{eAkswwucVB   //9910&'6J{FT+t}FiRmX;.@  //9/93333103#654&'#"&54632Ll^/9r@k99}M+/dyyw {7-NsB@#      /3/933/9333310#"54632#"&54632%%5_s{N/+ىs9:wJ6.'DeQovt5-Luguf7u@E    !       `//]q/9///99933333333333310##57573%377```J`X=@`^``F\^` Z l@:   lY lY ? iY?+?9/_^]3+3_^]2+39333333331035#533!!!!!!#\\ɳX꒶ݤ_@1   ^Y   ^Y??9/]3+3_^]2+39333333333103###535#5333#b?Y@0   / @ iY?+?9/33_^]]2299999333210"'!!&#"#>32332673V,* h dU#**g dNN ;323#>=4'7T#R|klfWD7S`&"d_Mq^`DVgIjt++B4 ,2)%mck,fcQ;!VF j@7"   !"    dY]Y?+?+3/33?/99933333333310%267#"'#&5#5?333###^i6_A6Hk%,Q NQVHu;yE@$  " ]Y]Y?+?+???993333310%##4&#"#33>32w 1qʘ}8Z@PZE@$    " iY?+???39393333310!#373 3#~ ᜱ/Fk`J@'  " ]Y?+????93933333310!#33?3 3#Z}=F_DfmmӲNTs+#}ND C@"    "iYiY?+9?+9?933331035!5!!#NyPsJ =@   "dYdY?+9?+9?9331035!5!!#PNTwG}}Z":@   #$iYiY?+?+??9999333310"32>54.'2373#'##"$5ʞ[\ƙ;  9奻G+\<[ncJ`pVa1^"@  ]Y ??+?933102&#"#3367>C2%#0j  4Z^ 69Jy"QOH8>]I#*@ $%  kY?+?3?399310!#&'#367367>32&#"ǻ? 6}.865ra:$#%' KsHrgZ ,'{^(*@$ )*   !&]Y!?+?3?399310!#&'##337673367>32&#"Ӽ2* Ӻhm Ľ  ;g`RC2%LjMbJkZW>Zk#OMIGTR oh $^@2"&   %&$!  ]Y  $!dY$??+?9/_^]+99993333310654&#"#527&546323673#2('3>Oxk)3rqwdKT'WO@+99TZpit4{T;@" iY8i0??9/]q]]q+993310!#3!sVyJK@- ]YM]}??9/]_]q]_]_]q+993310!#3!y鴴J7q\^;@  ]Y aY?+3?+?9333310 746324&#">ыYO^xeGO?*`u{#^Qrr!,@ _o/]/]99//993310'%'JII)IImmml!h`-@! / O _  @/O_/]]/]31034632#"&ӕ+?,+?:0,?!?#;77;6=8{%@ / O _  /O/]/]3104632#"&5ij?,+?:0,?ii;77;6=8#@  / O _  _/]3/]310!!4632#"&@?,+?:0,?ok;77;6=8_/]22105!53llT;@?39310 !#!b;{ T@?39310 !3! &@  * /33/9]993310#34632#"&Nu3A>>AB==BX7BGI@?LJ$@ % /29]9933103##"&54632u3C<?BD=;B;BHHB@KJBIHC@KJfu-"@ /3]2993310!55!-9?9910#3Nu35?9910#3Nu35- ;@)@P``p0 _/]3333/]qr10#"&54632#"&54632'673#3..2:&)88'.2:&'8 09y3046.52255/6.522dY ;@)@P``p0 _/]3333/]qr10#"&54632#"&546327#&'533..2:&)88'.2:&'8y903046.52255/6.522gYd+G* @ 3 @  _   /]33/10#"#6$!3 N`" zt3 @  _/]22/103 #&$+ #bO 3Ľtz 9@'    /_/]q33/].]].]]10.#"#!2Oh. $@ /3/99993310!#!5!3d+\+ $@ /3/99993310!#!5!3d+%F $@ /3/99993310!#!5!3n!ZZ @  /3/999310!#!5!3n!DN @ /3/999310!# 7 3g\=H`3R "@ /3/9/3993310!#!7!3bH3o`RN @  /3/99993310!#73^J^sN @  /3/99993310!#5 73gRۇjh0hF@  /3/999310!# 73qZyfkFq @  /3/99993310!#73q_ZGd)5 @ /3/999310!# 7 3RkGHyN!5 "@ /3/9993310!# 7 3Rk`/L-!P "@ /3/9/3993310!#!7!3ysdH^- @  /3/99993310!# 73`wcFFH@ /3/999310!#73vq=Df-q @  /3/99993310!#73qFsGVH!% @ /3/999310!# 7 3>{GHZ1#% #@ /3/9993310!# 7 533X3'5g% #@ /3/9993310!# 7 3D{rVJ1}q' "@ /3/9/3993310!#!7!3by R1X/@  /3/999310!# 73HՇH7%q @  /3/99993310!#573q>{G\1# @  /3/39999310!# 7 36}MH)R/) $@ /3/39993310!# 7 530XAuP/j5 $@ /3/39993310!# 7 3NN-qT+o5 $@ /3/39993310!# 7%3Nu7T+}/@  /3/399310)733+NT-)q@ /3/999310!#73qB=T-)P@  /3/999310!#!'!`sboL #@ /3/9993310!# ' 3\H6fy3L #@ /3/9993310!# ' 3VH)hy?L #@ /3/9993310!#5' 3THhy-^ @ /3/999310!#' 3P5fy=Lq@ //9999310!#'3q^hy"@ //9/3999310!#!5!3qT; &@ //9/399993310!#!5!3`/h{T &@ //9/399993310!#!5!35%"@ //9/3999310!#!5!3@P@ //999310!# 7 3i``ybVL "@ //9993310!# 7 3e`;H`FF $@ //9/39993310!#!7!3gb+\t]^L @ //9993310!#73^'ezL@  //9999310!# 73e\هseRdZLq @ //9993310!#73qe^=ddZ/@ //999310!# 7 3Hu7T`H?9 "@ //9993310!# 7 53Ru9HpHF? "@ //9993310!# 7 3Mw\sX=T9H? $@ //9/39993310!#!7!3lwo V=1?@  //9999310!# 73\w߇5:=?q @ //9993310!#73qXw1-B=+5 @ //3999310!# 7 3N}5H)1q5 #@ //39993310!# 7 53N}<Au1]j5 #@ //39993310!# 7 3NN-q -+o5 #@ //39993310!# 7%3Nu7 -5@  //3999310)7331N߇ -P5q@ //9999310!#73qN3 -yL@  /3/999310!#!'!nwJ{L #@ /3/9993310!# ' 3nH J{3L #@ /3/9993310!# ' 3nH)T?J{?L #@ /3/9993310!#5 ' 3nHu^J{-L @ /3/999310!# ' 3n5RjJ{=hq@ //9999310!#'3qo;L{L@ //9999310!#'3kNf{F $@ //9/39993310!#!'!3bj\L "@ //9993310!# ' 3\H5gyFL "@ //9993310!# ' 3VHiyPL@ //999310!#' 3ifrq\%Lq @ //9993310!#'53q^g"@ //9/3999310!#!5!3XV9ZB^ &@ //9/399993310!#!5!3cf)9% &@ //9/399993310!#!5!3b-%w"@ //9/3999310!#!5!3ZV@ //999310!# 73f^ q%^`V "@ //9993310!# 7 53o^h^xX "@ //9993310!# 7 3q\3Hmg1ZV $@ //9/39993310!#!7!3bL+Vm\V@ //9999310!#73'^{^\q @ //9993310!#73qu\/3g7 @ //3999310!# 7 3=q+\=LD7 #@ //39993310!# 7 53Po+^-L i7 #@ //39993310!# 7 3Po?J?LL)7 #@ //39993310!# 7 3PqX/XLBb7@  //3999310)7331PqLb7q@ //9999310!#73qPq?L{H@  /3/999310!##'!y\1F #@ /3/9993310!# ' 3{Ny1PF #@ /3/9993310!# ' 3{Hb1F #@ /3/9993310!#5 ' 3{HtD1\F @ /3/999310!# ' 3{HX1)Fq@ //9999310!#'3q{91@  //9999310!#' 3wbL^=5 $@ //9/39993310!##'!3ws;s=9 "@ //9993310!# ' 3uHXqHETJ9 "@ //9993310!#5 ' 3uHHG}9@ //999310!# ' 3uHHG9q @ //9993310!#'53qw>K@  //9999310!#' 3[VHZdbVs @ //9993310 '53#/[{b $@ //9/39993310!#!'!3[HVbk^ "@ //9993310!# ' 3[VHB1by@ //999310!#' 3_VHLdy}Lq @ //9993310!#'3q^d+"@ //9/3999310!#!5!3LR= &@ //9/399993310!#!5!3aNA%1o5 &@ //9/399993310!#!5!3qÇ"@ //9/3999310!5!3#d+VL @ //3999310!# 73e\-yfL #@ //39993310!# 753e\ }VyfL #@ //39993310!# 7 3e\j?yf)L #@ //39993310!# 7 3e\=J3yf6P@  //3999310)7!31i\y whPq@ //9999310!#73qi\;wh/@  /3/399310!##'!l-T5 $@ /3/39993310!#%' 3H{-T75 $@ /3/39993310!# ' 3HJ-T+ $@ /3/39993310!#5 ' 3H/P% @  /3/39999310!# ' 3}H)/R))q@ //3999310!#'3qÁ)-T/@  //3999310!#' 3TH7H' "@ //39/3993310!##'!3eyT19% #@ //39993310!# ' 3{Nq}1JV% #@ //39993310!#5 ' 33h5@% @ //3999310!# ' 3{H#1Z%q @  //399993310!#'53q{Šy1H@ //3999310!#'3vfD=- @  //399993310!#' 3mwbFFcP "@ //39/3993310!#!'!3sXdH^5 #@ //39993310!# ' 3kL!-L5 @ //3999310!# ' 3kL!Ny-q @  //399993310!#'3qs!HVF@  //3999310!#' 3RZZjfyN @  //399993310!#' 53LRHh0hjN @  //399993310!#'3}^s^JR "@ //39/3993310!#!'!3bqlV`sN @ //3999310!# ' 3\H3`Fq @  //399993310!#'3qZ)d @  //3999310!#!5!3D $@ //399993310!#!5!53'ه) $@ //399993310!#!5!3sD $@ //399993310!#!5!33\+Շ\q&~ ?HG%+555q&~ @0/%+555q&~ A0/%+555q&~ B0/%+555q;&~ W3-%+555q;&~ V3-%+555q;&~ U3-%+555q;&~ T3-%+555& ?x@ +*%+555& @x@ %+555& Ax@ %+555& Bx@ %+555;& Wx@ %+555;& Vx@ %+555;& Ux@ %+555;& Tx@ %+555y& ?0/%+555y& @-%+555y& A%+555y& B-%+555y;& W%+555y;& V%+555y;& U%+555y;& T%+555& Sx@ +*%+5555& Rx@ +*%+5555& Qx@ "%+5555& Px@ "%+5555y& S0/%+5555y& R0/%+5555y& Q3-%+5555y& P3-%+5555{ <@  iYiY"?+?+??9933310%#"'532654&#"#33>32 Ͼb:GUfo 6s un;\u{N;@  iY"?+?3?3999333310"'53267##33&53b:GUfm {unmV"U@- #$/?iY iY?+?+?9/9/_^]93993333310!"=332654&#"#33>32㹶 5uĵɾռ[v&W@/&  &'( ]Y   #]Y#]Y#?+?+9/_^]+993333310!2654&+532654&# '4632#"$5bPmXϴȻӝy з3ǻjL@2 @ H/_ /]33/+33/]/29310#&'53%46325>5"&!!VCC=-27jx8A-=4_4.D5mz L0+/jO@3    @ H/_ /]22/+33/]/293310!!46325>5"&673#j_F>-17ix8A->:"CVZ4.D5mz L0+/j L@2 @ H/_ /]22/+33/]/29310!!%#&'53%#.54632j_:VCC=-A8xj72-=Zݩ2/+0L zm5D.jO@3   @ H/_ /]22/+33/]/293310!!#.54632673#j_ >-A8xi71->9:"CVZ2/+0L zm5D.h! #@ o@_/]]q]2104632#"&>73#8(.2:&(8+r%)Ews5/6.522L7I=6Z 3@   p   @_/]]q33]]/39/]3104632#"&3673#&'`8(/1:&(8{ri~a3<h6/8-422Js~?`f1 '@    /]q33/]333104632#"&%4632#"&!!8('::'(88&'::'&8q`h6//642246//6422o /M@5vO _ o   , O$$$$( H$)!$@_/]]q3/+]3/]]33]3104632#"&%4632#"&".#"#>32326738('::'(88&'::'&8:+SOI"11_ o\-UNH /2] nh6//642246//6422$6.pz%6/rx?G,d@X  @?$@IH $ 4        :` p O  ( H  @_/]]q2/+]q^]3/_^]]]+qr^]10".#"#>32326737673#'MIF&*h hU*PIC+&f e1n#7w$,8pz%6/pz5;~EO1  +@  0 /]q22/]]10!!%#&'53`y71Yd1  +@  0   /]q22/]]10!!>73#`s= aw[#.KZ (n@$%O_ @0,/H@# #H %%% %%%%0%%% _/]3333/]qr/++]qr]9910#"&54632#"&546323>73#&/3..2:&)88'.2:&'8{5s38q6B(,@3046.52255/6.522#N78M#@KJ@/ @` _/]3333/]310#"&54632#"&54632!!3..2:&)88'.2:&'8`3046.52255/6.522HXA@-  ( H  @_/]]q2/+]3/]]310".#"#>3232673!!'MIF&*h hU*PIC+&f e`$,8pz%6/pzב/ /@   _ o  @   _  /]]q33/]3104632#"&!!h=-08:.-=`L<6=56=8)/ #@_ o  / ?   /]33/]3104632#"&!!h=-08:.-=`<6=56=8^ $,m@F ) ,-.',,,$0@5 ,"?O/?@H _  /]3333/+]q33/]]]q39/]933104632#"&%4632#"&#"&'3327673#{8(/1:&(88&/1:&&8q Vg R-[qe76/8-42246/8-422xz96ol`wX^ $,m@F  %(-.)&&&$0@5 ,"?O/?@H _  /]3333/+]q33/]]]q39/]933104632#"&%4632#"&#"&'3327#&'53{8(/1:&(88&/1:&&8q Vg neq[3L76/8-42246/8-422xz96oXwm_j #a@A  #$%_#o######//?@H _  /]3333/+]q33/]]933104632#"&%4632#"&!!7673#{8(/1:&(88&/1:&&8p_R-[qe76/8-42246/8-422jl`wXj #a@A  $% _o//?@H _  /]3333/+]q33/]]933104632#"&%4632#"&!!%#&'53{8(/1:&(88&/1:&&8p_eq[3L76/8-42246/8-422jXwm_^; %M@/"%&'  %@ H%% @ H _/]33/+3]+293310#"&'33267#.54632673#q Pn]]>-A8xi71->9:"CVv~x5/22)1/+0L zn4D-^; %J@.  &'#@ H @ H _/]33/+3]+29310#"&'3326?#&'53%#.54632q Pn]]DVCC=-A8xj72,>v~x5/2231/+0L zn4D.^; %M@/"%&'  %@ H%% @ H _/]33/+3]+293310#"&'3326746325>5"&673#q Pn]]P>-17ix8A->:"CVv~x5/22)5-D4nz L0+/^; %J@.##&'#@ H @ H _/]33/+3]+29310#"&'3326?#&'53%46325>5"&q Pn]]RVCC>,27jx8A-=v~x5/2234.D4nz L0+/F@%iY kY ?+?+?3?999933210!# # ! #"'5326! 3}w9NQnEB4=;Q>T4fi<{6wm"=HTJE@%]Y ^Y?+?+?3?99993310 # #"'532! 3 # #_v="l#1c bJjO@*   kY  kY?+?3?9/+9933333103 #!##! 32654&+o&-Mը%ĶH!f^'W@0 %%()  ]Y"]Y?+?+???39933333310"'##33>323 #"32654&w @n٣)N==6ZP۸#-|@F   iY:    kY  kY iY ?+?+3?9/+39/_^]^]]]+9333333310!!!!!!#.54$)#"!3Ty ݷq8^2Ξӝ!^'.@H  +# ,,#/0  +^Y++++ "]Y"" (]Y %]YaY?+?+?+?9/+39/_^]_]+9933333333103#.5463!632!3267#"$'!!3!"%"!.9~ηvXmXo swӁ/ wwm-&!PjZq=@     ?3?39933333310!##3'773'kjgi<m˰m#J;@     ?3?39933333310##3'773ɢZV-J!XZ,T@. #-.iY + iY +iY+!&kY!?+?+??+9/_^]+933331063 #"&'532654&#"#! #"'532>!}L1PMJ~+z8USmE@4=:Q8GH כ1Wul PJ$V@1 %&aY ##]Y# dY aY?+?+?+?9/_^]+933331063 #"'53 4&#"#! #"'532!R;Ќjl N;`vCk%Nq <=/cq$u@C !"%&iY !iY!:! !!!!! iY #?3?3?+99//_^]^]]]+_^]+933333331063 #"&'532654&#"#!#3!3%L1PMJ~+z כ1Vj J @P !"aY ]YE  aY?+?3?399//_^]_^]]_]_]+_^]+933333331063 #"'53 4&#"#!#3!3R;  Ќjn~ M<q <=/J7 6@  " iY  iY?+?+??933310%##!#!%IJ 6@  " aY  ]Y?+?+??933310%##!#!ȴ{PJN>@!  iY "iY?+???9/+9333310%##4&#"#3$32|f-vv"2;\VG@%  " ]Y]Y?+?+???9/93333310%##4&#"#33>32w 1qʘ{8Z@PZ (@     @ H /+]22939910#'##'##'5R!11!11!P!ffff!)Vq@H   _o   sY  ??+?9/////_^]]999331023#"'575573%%ZZtD۰Zj&(LJJJp͑u=G@ G.@`/#G/@f)G0@G@#G@ ^ ^ v > ^   D *2 (\ \ > < Z 4Copyright 2012 Google Inc. All Rights Reserved.Noto Sans UIRegularMonotype Imaging - Noto Sans UIVersion 1.06NotoSansUINoto is a trademark of Google Inc.Monotype Imaging Inc.Monotype Design TeamData hinted. Designed by Monotype design team.http://www.google.com/get/noto/http://www.monotype.com/studioThis Font Software is licensed under the SIL Open Font License, Version 1.1. This Font Software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the SIL Open Font License for the specific language, permissions and limitations governing your use of this Font Software.http://scripts.sil.org/OFLff  34566778:;YZ[\_`ders}~NOGHTU > ? W X o 45Z[  `bddss!#$$%%&()+,-/1256689::BNHIJJKQRRSSTT Ncyrlgrek$latn4 kern8kern>kernDmarkJmarkPmarkfmkmk|mkmkmkmk        *:JZjz  %~ & )` +B @" P Q ^ _V b  de dF`bddss  %(3!-:/6G8:OBNRHT_%$=D]4KBj77NNSV\_27 BI^alq~!WYZkl""(UZW]f]kngqk{QQbhssvvl $****0*****************6<***BBHN*N6**T**TT****Z**T`````````````ff*lT* &,28>DJPV\bhntzbn,bn "(h.4:@FLRnX^d4jpv|JJ"J<jp. $  *0:6<<<BBHNTZ`ffflr>r>rx>~x>,,,,f""""n:4:nnnn &.,2,2,2,282&.&.&.>.DJ(DJPV\nBVbnhRntz@bnF,FlRnt "(.,24:&,2v|@>FL>RF~>F8XJ^~>djVpv|V"hnbhJ^bhnbhnbhnJ 22$*06<BHNTZ<`nfnnlrxb(~nN,.,.,..,.,$n*n  n6&  ,6  268>DJ$J$PV$n\*dbhzntzRn.RnnRnnl2n>8J2 ,"(.4.b*:@nFL*nR*X^h.d.jp.vV|@ Vj|xdj.(T0>V\p"J<@ Nd.L""$*06<xBXHNTbn2* 0,6Z@0`flrx~R( &<,nr2>8,,>&.Dn"JPV\bhn4tz,t\D,n, l tx, <\nBbnf"lr(>.~>.4:bn@FLR>X^<Rdjpv.|v..|2\Fpv0nBnRn8n,n* $ *06<B6Hbhn>N~0,TpBZ`Bf,lrxZ~D|4v@b,n*n..F4@L(Zn4@4@4@N>>RndjZ4RnnJJ &,22t8>:D JPZ.BVBZ.*N\N\bh$n"~<*<*ntz<b*.2B $pr0,T0,0`T0`T<BXdx4n"4,@JnRZ(<BXdj\ "(.4:@pFLpR8X8XvhFL.X^d^N~0,6Rdhj4pv|djdj2.vhFLX^4J^N~4~0,Rn4FRn~~nJZN, (h.  ( "   " FL@ $FL * $FL * 0FL 6 <FL~ BRn BRn H N^ T Z ` f l,2|&, rv| l,2&, xv|&, rv|8 ~J\ "V  V  bhJ h bhJbh BJ z Dtz D   @&X N N  N n ~b *~ n r n  *l~!!!!>!! !&!! !&!,! !2,",!8,!8!>R!D!JPV$!P!Vl!\!bl!\!bnR*!h !nr!t !z0,! !z0,!v|!x>!!$!!*!n!!x!Z!B bhnJbhn!ZD!Rn!!:~:OfdtL~L  XX44[[|FDD| P  < ll::gg:jII00vhv\h8Dh8lh,0hlLvv H%%l0~R XXl[[l l  llLX0@0:Dx@\D@D@@v@l@lv @ $DD,<Dn ,:,XNNN,llX,X<bbHH8X\lflfb,b4<DTDl@[0[[<<|Xn,pnl<0<DhD<h l, <l< nl l`L,4< <p,,H,:> >:0v,vvLx<v<%,,DlI,I0\h%@l%@|@D$(D DPXX [ 4P[ l  <lPv vLPD jP:vH,h0`,h|[,0,lvxw,hTbth!!&&5 6,@ `@FFp<n< V 8 .8pDN${ {55IIN&S@ + 94,,,<,l,@ l(,N@("\",aIppCCD@ll|hq p:dnnXpp/XXzd~TG0G,,$|,,T@@@|jhVThTV]]It  \\,rlblpvp@p0pppp]h]pDpHHH|h|HHlvTl>>pXpblHRRl[p0@0"Xl,  p@D4:l,:,:pppglg%Il@IJ%dd## Pb`aHNTTHNTZ`flrx~Xl0ll *l \+D,l XN,0 $=D]4;CHNOPQ?ARCCUGGVJKWMMYSSZWW[YY\de]xy_{{ab  &,28>DJDPV\bhntVzVVtPPPPPPhhhhzzzzV `~du~uTWS&n~B~x>~H-J:J@J\J:JJJJJfJ<J6;JJ  *^JTJrJbJ X^ $=D]4679;<*+>FI@^aDH "(.4:@"FFLRX"^"@djpv||^^^vvv^^vv-x~x!qL{wJxdxyX*\\#9p8J^J\J^@R%mF@JJJJ`J ;A$=D]4KBj77NNSV\_q~]""eU&QQ'bh(ss/vv0   1      & , 2 8 > D J P V \ b h n t z    "(.4:@FLRLRX^LRdj@F pv|@F            J J J J                   $"(.(.(.(.LRLRLRLR @F @F@F@F@F      " " " "   *0 (. (. (.  (. (.6 26 26 2 , 2< >BF 8 >@F JLR JLR JLR D JLR JLRHNTZ` VLR \ bX^X^f nlR h nLR h nLR h nrx h nLR @F @F @F~ @F    pv pv pv | | | |      @F @F @F @F @F @F           LRLR zdj                           (. (. (. . . . . (. JLR D JLR                @F @F&,2&,2&,2&,2,2       8>HN  DJ  PV\b  hntz &6 2 D J \ bX^LR @F |       "(.4:@FLRX^djpv|   JLR  @F(.$ , 26 2 b^   :@FLR6 2 @F     (. (. JLR JLR   pv pv @F @Ftz< >BF 8 >    (.   " h n  |  $*  (. P VLR06 pv  "<B(.(.HNTZ LR`f@F@F@FLRlrx~djdjdj@F@F  $pvpvpvpvpvlrlr|LRLRLRLR@F   `fLRX^ &,28>DJPVPV\bhnDJtz4:dj@Fpvlr| LRlr 4:X^LRdj@Fpv| (.LR"LR@F    "          . .  (.  (. (. &:6 2< >BF 8 >@F< >BF 8 >@F 8 >@F D JLR JlR b^ \ bX^ \ bX^ h nLRf nlR h nLR h nLR zdj t zdj @F @F @F @F           pv pv pv pv | | | | |        @F @F @F BF BF          @F   h nLR h n  i<iJJ(N33ss''//11BB??ddqq}}FF{{NNJJ;;0 0 0s0000?000  000,/0100mm0d0q00B0FF==;;}h}0h0h0F0=0dd{{yyVV==BB{{yy V0 V  ``!!DD%%0F00 VJJ^^  }}##??BByyhh{{BBLL%%dd1130'00000Jhh0 $=D]4KBj77NNSV\_q~]""eU&QQ'bh(ss/vv0   1      & , & 2 8 > D J P V \ b h n h t z h , h h     & & & & & & > > > > V , b b b b b b n t t t t , , , , , , , h b b b n n n n h t t t t t h h h h             & , & , & , 2 2 2 8 8 8 8 > > > > > > J V V \ \ \  \ J J J V  b     b b b b b b b b b b b b t t t t t t t t   & , & , & , & , & , & , & ,           > >  "  "  "  "  " V V V h h h ( . 4 h h : @ F L R X   ^ d j p v | h 2 8 L   j D V ^ \           j     b  & , > t h h  & , & ,      h   b b t t   & , & , 2 2 > > F  h  , \ b t & , V      n    >  t   h 2 V b h h h n  h h t t $ *  D h h 0 6 < B H N T , j Z 6 6 ` ` , f l ^   r r r x &  D 0 ~  h r r              h h z h 6 h  P  6 h  , h h z  h  b h h t    n  h h h n h h h h h t t t t t z h            & , & , & , & , , h , h 2 2 2 2 8 8 8 8 8 > > > > > D D J J P P V \ \ \ b      , 2 b Z J003000s0'0000/0010B00?000d000q0000}0000000F0{0N0000J0;000 0 0000000m000F00=0;0d000{00000y00V0=0B000{0y000000 V0 00`0!0D0%0000J0^0 00000}00#0?000000000B00y000h000{000B0000L0000%000d001000 Z`"$&(*,./125678DFHJLNOQRUVWXL"LRX^djpv|jppdppX ,D  5D\N $=D]4KBj77NNSV\_q~]""eU&QQ'bh(ss/vv0j1jpv| $*06<BHNTZ`fljjjjjjrx|~NNNNf6fjjvvvv||$*`BBBHHNNNNNZflllZZZf$$0jNjjjjjjjjjjjj &,282828>NNNNNN>NDfffJppv|PV\bphnt*z6BHflB6jN  *     " ( . 4jjNN : @ F\ L Rj X ^f d jH p vjv |  p $ f  BB$      x6       N $ * 0 6 < B H N N$ T Z< ` f l r x ~ * <  F 06BHl   6  6 $   p    x | & , 2 8   > > D J  P V** \ b b h n J t00 z  66  nB BB H 2  J  T ZZ``fl h HZf xz%{N4RjHLbH$b=&Db@HE4HPHpppp(pbp\H`HupNpDpp\pDpH>2(bRHf  \Hd0L#3DH Hh]1 RHHH~_ pv 0H3HHH HHH=llHDHH\HhHH`u=HHHH)BHHjL H3tHH H/|@HHJ3DHpppbrhhppppJ 0lppR\/4p:bDXE 6@EGIKMQSZ ]]4:6<BHNTZ`flT6rfx~VVV V=VVpLV,bVV= VVDVbVVsV p`bss!#%% )+!/1$66'::(BN)HI6KQ8SS?`bss!#%% )+!/1$66'::(BN)HI6KQ8SS?@@ $***06<B***6HN**TZHTT`Tff*fffllfffff<<x:Ot`Txx@::@:0@TD d, djdd  $$&(,- 25"89&JJ(RR)TT*dd  $$&(,- 25"89&JJ(RR)TT*+    $*06<0 6000BHN6*00HTZ666666* +~t`V4\4H $ BHfl )`dos""PEKNO<-2"FEKNOFtsdtdpqt2200 0"""<"^^4 ,TT,T 0 0 0 0 0 0"""""""4<zTT 0 0 0"",,"""^T4T4 0""z   " !"!<!B!DFHIKKNNPS UU$WW%Y\&^^*+78=DJNORST^_`adnostwxyz{|}~$(**,,..0022446;==??CEGGVV[bddffhimmooqvxy{|~~      !! PQ UV]]__ggimosuuwwy 1P\bhjlpq{AFJLLNNPPRRUUWWYY[[]^cceeggiikq~//$79:< DFGHJPQRSTUVX  !$&+-/13568 : CDFHJV_biyz{~ TUV]_gopz|  "#$%&'()*+,-./013579=?AGIKOQSUWY[]_acegikl n p ~-Z&*24789:<$&*,.02468:GfmqrsuxQ\^iy{}    FHJLNPRTVXZ\^`bdfhjlnp~7$&q~< &*-2479:<$&68:G \FHJLNPRTVXZ\lnp~4$79:;<=$&68:;=?C U "$&(*,.0lnp~%&*24G\FHJLNPRTVXZ\-<$C U "$&(*,.0N &*24789:<$&*,.02468:G \^FHJLNPRTVXZ\^`bdfhjlnp~!~~$;=;=?C~ ~U "$&(*,.0"$&*247DFGHJPQRSTUVXYZ[\] !$&+-/1357<>@CDFGHJ TUV\]_ "#$%&'()*+,-./013579=?AFGHIJKLNOPQRSTUVWXYZ[\]_acegikm~$C U "$&(*,.0"$&*24DFGHJPQRSTUVX !+-/135CDFGHJ TUV\]_ "#$%&'()*+,-./013579=?AFGHIJKLNOPQRSTUVWXYZ[\]_acegik"$&*24DFGHJPQRSTUVX] !+-/135<>@CDFGHJ TUV\]_ "#$%&'()*+,-./013579=?AFGHIJKLNOPQRSTUVWXYZ[\]_acegik%&*24G\FHJLNPRTVXZ\   YZ[\]7<>@ m  < << <4FGHRTH]3579=?AGIKOQSUWY[]U( (DFGHJRTDFH( (V]#%')+-/13579=?AGIKOQSUWY[] ( ("( (   ( ( F@F`F( (  fmqrsux QV_bdipqrtux Q%V_bfimsvyz{|}~ !qrxQV_bi -V_bfimsvyz{|}~ !Pfmfms~~V_bi~ ~ V_birx Q V_bfim    y~ y~ y~    y~ 6  ky}     ghijnoprtvz{|~   i{    #iy{  N22 giop{|22 /  ky}      oy  }  n  = opwy}  !~~~ ~ops7 opw}  % gp| g|       p'  j~       I(W(Y2Z2[2\22%('(72224(5(Z([(m2(I2W2Y2Z2[2\22%2'272224252Z2[2m22  y}  5  gjz|~      op ghinoprtvz{|   ! gp| %  y}        %nixz{  g|   )  y}      j~  }   ghinoprtvz{|     p*  y}        }  )  jy}~    @  osy}         o}    +  oy}   Lcyrlgrek"latn0aalt2ccmp8ccmpBccmpLligaVrtlm\rtlmbrtlmh 0@P`ph< T"*2:BJRZbjpx&.6<DLT\djrz^fnv~ (0 $*2:BJRX`hpx$,4<DLRZbj                           LMW`bss!#%% )+!/1$66'::(BN)HI6KQ8SS? (B~FPZdnx  (2<FP ` a ` a ` a !` "a #` $a %` &a '` (a )` *a 3` 4a 5` 6a +` ,a -` .a /` 0a 1` 2a 7` 8a 9` :a Y G k l m j n o '*,./0I 4L5OZIL[IO  ; < = > V 7LMWlinphone-desktop-4.2.5/linphone-app/assets/fonts/NotoSans-hinted/README000066400000000000000000000007121376717241300257420ustar00rootroot00000000000000This package is part of the noto project. Visit google.com/get/noto for more information. Built on 2017-04-03 from the following noto repository: ----- Repo: noto-fonts Tag: v2017-03-06-phase3-initial Date: 2017-03-06 15:25:38 GMT Commit:60aa0da2ee84b11e78725b4577edc2e80b009d56 Initial phase 3. This is the first release of noto-fonts that includes phase 3 fonts in the hinted/unhinted subdirectories. The new fonts are Armenian, Cherokee, and Hebrew. linphone-desktop-4.2.5/linphone-app/assets/icon.ico000066400000000000000000001153611376717241300223470ustar00rootroot00000000000000hvn 6@@((L2 .~( vvf g g h infe f@DIOhmn     (,ef f g h i iklmoqqt%x(z,|.~/~1389:bfklxy{g99 *(  -888888-855888888888+84 !68& 26 288/878888#888888" 288888888884/8888888888.)888888888487-888888'$$99(0@ff g h i ijkloppqt.}06>?CEJMNVY]]^bel| l==5<<<<2:!'<<<<<<<<<< '<<<<78<<<<4<-4<0,  $;<<8"<<<<<< &<<<<<<# )1<<<<<<<<<<.* <<<<<<<<<<<<<<<<<<<<<<<'<<<<<<<<<<%01.<<<<,  ==( @ffgf ff h ijkkllmopqqst"v#w&x(z+{-}.~466789;<>>CEGHHNOQRSY^bemtuvwyz|fegfpllpml1IQPC/ )8JgkkkkkkdA*WkL$^kkkkkkkkkkkkk'%dkkkkkkkkkkkkkX^kkkXL=47?P[kkkXIk\<Fdk9a? K^%". ",,! VkkkkkfU7kkkkkkkk0Ekkkkkkkk8,3UhkkkkkkkkgS2 '!XbkkkkkkkkkkkkkkaYUkkkkkkkkkkkkkkkkLhkkkkkkkkkkkkkk_kkkkkkkkkkkkkkd#IkkkkkkkkkkkkkZ dkO Cbkkkkkka< B*ACDFGHKKMNOPQRTUVWXY]^_``abdfgilmmnpsu{|}~g ge eU`q.                      .**+*..      7HPLE1?rf1Fz \HL_CL  r}E  e rWCjP1:\x  [ 6gz[w6 L2 ( Lw?J j o:SVW  (Pcpuuj_J' T|vCk }} F% ?Huj=H=:xo'\} tXvb[7 j6 mSv 'j }S_ eC('o L|: Uf#^}yV4 %31#  ,.)+)+.,(@f fff imr"v%y+|0gfff f fgf5;?AEJNSX\bfkqt|gdgf f ge fdfii d h jUUzzwwwwwwq owwzzzzzzzzzzwwi izzzzzzwwwzvvwwzzwwwvvwzzwwv wyywwyyvhoyw wqq$(,//.-*&  (8eeeeeeeeeeeeeeeV/$)Uee._eeeeeeeeeeeeeeeeeeeeeeF&6eeeed'Veeeeeeeeeeeeeeeeeeeeeeeeeeee2!Feeeeeee)ceeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeAFeeeeeeee3%]eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee59eeeeeeeeee!Bdcc Onw>赁K9$:o6꘧ `ErH/ ƛ%K裴l(A{?e_Dȋ0)ܭmmt龪L xG06~BS^0 7ZWkﯷ:8=ԯ;< ƈ^gBH 8i8v41;@?!\iLb\zBAxey[JP73@G > ɞ)_,'{ 5F2(OH6STSbp'͎b388{!5wkk)4'Ix[߼=i'i)x[×Osqط+O|N7FE$V,AφRO^0Ci~al8Ou0O3=(ll4M^/< :!$<Э cb.o<4RT4E|JԥCI';G"X~ :!$ᢳB̎WPTHI\";0K"#O DbTH Q"1*B$F@Ĩ! DbTH Q"1*B$F@Ĩ! DbTH Q"1*B$F@ĨM #/˻K.cށ0vulx`P:uQw(.P::y|` i~0_x$[`#3'ju4I^.:D*<&],bl#&9vQUi&A9 uP{ Mp"o[]3j< u쓵2kꓢC-heZ OŁ)z! or#I.A)#EGr4ǏyޔnDd;]z#<7Blo3$l@B(ݧ\j;U~Fgp8Ϟ~}k?tBQIqDj`]':@!wӬ5\tǐ ֆ$K] )sP$I"Ed5i EG IvNo{(QToyYtd,'ɯ[>Et$Uz;VAR g<|h3 ^N} P=d ܷV>1Hހ tp+7(\]z#Tm g|  \]z#8m-@+,T}r1H)%4h#4puN,P :JF;`NȀ]h~Q2dv9gˀ!:Iw3עcd FD i- )rc;lrͅgAV<*: pdW!:c'm.[=ޛC(9 @#o2N?AΨp]>Xt a,`.cLz@O+w $`\ȹ?D ('#*oţpd=ϋvR9c~!:`jk [tr̢IrFNꀠ[UARXEH9c爎@o ipNva|*~":FZ8|g@8\ťP}|91GGDG YwOEGH9 sc,.qÎ-)?`Nuؙ[[\tJ)fw{Tt”qd\o+ēa]':*ȪF»_s# @4¯<j)O84>w+DG&iO~S:gGGB. Etau wC͎¯Ne `ϹݷcCv/yW?X sw]>ion9~5ԑ;nƿf7~0?Z܌n]j8>/n@b377;)ḯ={s[d 0m\C4!K\s6ux~wr {][( ;5̮?":BFiLpy'Ul %*4Zt hZ: H (6n> w(gD}?۸."@p)9:-Kҋ @  w뚝:?ݖ?fe @RT{AZ{] @qN&Vm5}0+au:'CQd Wa W|j!puqOO~ᝈ`~\EC,B5z*P/++|qC#;`q,GN4?`:|y`Z10_zp#G!XuGO$6򖞇d5*Ye\:t",ڲa/*B$F@Ĩ U\*:q !%W[3~!Xyކm() od>X@tŔl=Ԟɯ$.Zb}X)`Vo͇Kr}FPT.*FMo}y# cjѩSJmZh@6ёIh~57 Gm1>io Fz7:y}":z9xGwԞ 8s rϧ݂,*.EތLxݓX0o ):>眷|2:r/̏։!$&z7WtojaDm]݇ݻZ @N-z+A1{P{^#:Ix$ځg;aTî?pjcwu݇BZI@bNOl?s:C6ǰ>Uv6(S,R*I;2Ot?Bo䌟':FQX G(xW#'3nU KcnBɽ,rtO%}k/$:pyB>Dt&vA0 gTI]q4.nCDK*ITWjZ<z#  8ܿ gAR UtA o{Mt b޲ #d *_]cR{^CW~> lF lvnAhsBt"!wҕ@"BOL|A8 sof*>gG9-":pTI#`ꢣ$s` @7!ߣ~0 c{pbn}:0޲ R hA?Gmd| St aډGB8c=0\6Iˎ'NzD$Ko{ C*㈾5 ]sBP\ s[Fr DH;*$|fb~+: (mX)Ҏ Y0"@o N$UN]5M;*$3oBCmKto{ h|RXw ѫVtQR { p=@jÈ[{1r<Ox iCJ)sRG(F7_e4?|?|r8DPW"-\ӯT± >;ba+RE'<_Gxe-Z?y?QA9@@#W&0BlbD] [?OYr>˷Ee_E{H]n@lb{)im%+|c.x3H@ $7< @iR:)L ^T˔6TU\ OxQ`yܿ)m˂Ere82U.DdtQ/YPd"EFh3hlv+0u oܷA4\,Pϰ{+Y,,sPd:w+{oKoщZdVW 澍ɝ<շ[6s3Gv@a"oW -# YuL)ϐ;z<’s7v?3UẸ'\_WA:HZ ďut7}]W)*.9;dUuS)*z*,[  \g羯Ϡzp7@`j`̼aҭ 0l& pL2zѹ!i`&Ś]1{\4`֭ `|vbp'Dg#5z%2PHi@q 7~́ |6>= A ^a<LI^ @Hpc4Tu=qEp\?z ]-Q^ nB텋~s4v߭y`w^BH(*` w~p~} &ͩ6\gka_BZc6n/\/hmV 8W@o8+ڲ8kBg{6m\zBNQTþ_mlnb`|*8>H+K^mv ƛ}v(y>-e :y9}3e&S֙}g}ߚvshc+VO=!c C`8EJ6vsc{ Z/IENDB`linphone-desktop-4.2.5/linphone-app/assets/icons/000077500000000000000000000000001376717241300220275ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/assets/icons/genicons.sh000077500000000000000000000022701376717241300241740ustar00rootroot00000000000000#!/usr/bin/env bash ## ## Copyright (c) 2010-2020 Belledonne Communications SARL. ## ## This file is part of linphone-desktop ## (see https://www.linphone.org). ## ## This program is free software: you can redistribute it and/or modify ## it under the terms of the GNU General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## This program is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU General Public License for more details. ## ## You should have received a copy of the GNU General Public License ## along with this program. If not, see . ## for i in 16 22 24 32 64 128 256 do mkdir -p hicolor/${i}x${i}/apps inkscape -z -e hicolor/${i}x${i}/apps/icon.png -w $i -h $i ../images/linphone_logo.svg done convert hicolor/16x16/apps/icon.png hicolor/22x22/apps/icon.png hicolor/24x24/apps/icon.png hicolor/32x32/apps/icon.png hicolor/64x64/apps/icon.png hicolor/128x128/apps/icon.png hicolor/256x256/apps/icon.png -colors 256 ../icon.ico linphone-desktop-4.2.5/linphone-app/assets/icons/genicons_1.0.sh000077500000000000000000000023251376717241300245530ustar00rootroot00000000000000#!/usr/bin/env bash ## ## Copyright (c) 2010-2020 Belledonne Communications SARL. ## ## This file is part of linphone-desktop ## (see https://www.linphone.org). ## ## This program is free software: you can redistribute it and/or modify ## it under the terms of the GNU General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## This program is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU General Public License for more details. ## ## You should have received a copy of the GNU General Public License ## along with this program. If not, see . ## for i in 16 22 24 32 64 128 256 do mkdir -p hicolor/${i}x${i}/apps inkscape -z --export-type=png --export-file=hicolor/${i}x${i}/apps/icon.png -w $i -h $i ../images/linphone_logo.svg done convert hicolor/16x16/apps/icon.png hicolor/22x22/apps/icon.png hicolor/24x24/apps/icon.png hicolor/32x32/apps/icon.png hicolor/64x64/apps/icon.png hicolor/128x128/apps/icon.png hicolor/256x256/apps/icon.png -colors 256 ../icon.ico linphone-desktop-4.2.5/linphone-app/assets/icons/hicolor/000077500000000000000000000000001376717241300234665ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/assets/icons/hicolor/128x128/000077500000000000000000000000001376717241300244235ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/assets/icons/hicolor/128x128/apps/000077500000000000000000000000001376717241300253665ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/assets/icons/hicolor/128x128/apps/icon.png000066400000000000000000000073151376717241300270320ustar00rootroot00000000000000PNG  IHDR>asBIT|d pHYsItEXtSoftwarewww.inkscape.org<JIDATxyTՙszeQhD@ \"jAQ't43'#8όq5&yb4YmDvQin{QءnꜪ׷Wuu|9c$KFF( 2]-gɸ[Po#oHְƑe?8M}AU" UEL&YTJW$"cdn=|/&W _@!bH9Hw a$ )dLC(p8 N`'0@ P(p8`vX/۳Ԧ!eh D$2^_lU{TH,{Ԧ% ,4"9pbu>47w35nYk]F5 be95^O_|eR'FYGB_Mh݇:U ڰgl NZg! zٽ&>~6oڲBG]u֐۵óN 2&Wޏ,l9uoR7AkuKi p {EǤ6,$y:0K2Ik 2^[͉ŽfDq;a݉vn)C*OT"}׊1+(&?ú-g[3uC1SE9wr4Z }QIj"cu9{'r mc+rNx>vQ4Bܣ+rDRo4K\:%w#w1'j2ך( ›@䇳QmZ `Baޓ-C rmtx Qjՠqwb+|_hj1Ѿ+:"<-MwD(#tNbmB[jLlteMG3T NRRr`X' B1SD:oߖڼc{ r??Aݰ d˞%ଚMaRv8k_SIVAx+y2u-+HmYѮ 7`fE_5lX8AM|`X V ZD &'cN|LfbV%tDB^.ϓ+פ> ǯ#qw_vRp '%:*ߋѦseI,R[RsJ:*Fi޳Cno_uL/T-^geygIrg]{۵o:W^ϿhhaW ; $9_{ ]NtsHsF:uҝ1) 3(3@h9Mn5VYҩ#i A]!0ݎoݗuaCX@uId?T仿#I/,C% "cn(8XJ(cDI}Y8k"YTw&v kM]!Ծe@} ':ᬙCȄƵy PB}Рk1[0L4%@x&MvRڴԦluFf^ؽ.;S^n?!-Fo=ce?/݈gށm_g:vXg j-CD08'Jb>@H7ɡ_Mޫ[R^#uKrzd*,Zc(薑p+WrW׃薢3@zCMyW) FuSpVSM-%4j98kQ+tK:?' n}GF~Jbu= ms^6jRKIJxΛ675O\Z$?xre ]0IiOYӵDn!~g$Waburx{6R$?Nv:sFQ+~^Wu FĮk6$ח?67_0{ݾEM0T0w#rE%O\5+aGJt]03b' 5"#4ƒ'\1$-+GMV@zh8kCX{HO*-N^Wƫq?_MjR~afʶ; {y}6v-) MDS?̎1vAU`AW ?tHz/Wl۽j~=Ž`v-ٰ@XH7@1ɿ2K`'0@ P(p8 N`'0@cAa4BkH)4ΰ6@,"JRܤ9ktH,O;%b:>(Fb: y]H[W^oL uI & {NJ7l,4[6X[e*mqIԯI \TboXÀ7K 6ak'YFS-zI[96J)fueD1q1파6Lq!P¼A+X rnN'U!IENDB`linphone-desktop-4.2.5/linphone-app/assets/icons/hicolor/16x16/000077500000000000000000000000001376717241300242535ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/assets/icons/hicolor/16x16/apps/000077500000000000000000000000001376717241300252165ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/assets/icons/hicolor/16x16/apps/icon.png000066400000000000000000000006221376717241300266540ustar00rootroot00000000000000PNG  IHDRasBIT|d pHYsvvN{&tEXtSoftwarewww.inkscape.org<IDAT8c|1!a4di&J4c8.N <o u2fhM-Hu)"--ЊbLJ}~N_ B{BB$&VAv`t 6;ou{`g@v"G)S̤)fT嗓l筵wm:Wq޿@s $Fw?7v'Յ=` Ar3bO*_R]x5c=>y:.{FߜAt$G1g@ԳTf[ #x=WXq"j)3 < IENDB`linphone-desktop-4.2.5/linphone-app/assets/icons/hicolor/24x24/000077500000000000000000000000001376717241300242515ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/assets/icons/hicolor/24x24/apps/000077500000000000000000000000001376717241300252145ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/assets/icons/hicolor/24x24/apps/icon.png000066400000000000000000000012231376717241300266500ustar00rootroot00000000000000PNG  IHDRw=sBIT|d pHYs-ItEXtSoftwarewww.inkscape.org<IDATHKhQ@{i&4B ՝ju!(BE1QDХ E"@pUp#* RnDMLҙd޸NpQ>Z 72+;Qy!DvV Rbѽ"]dٗ $3Mqb}k/:AQ>'sx"҄λԮ k~}785tysx, v M{QT Z^#aHlOݡ~;ר; PgWC'{riZ^(ڟBΛbuzv3ˀdk;ȜK|Dv?GښO?-&-#{!{C+`& $"˫g*gi\5?dfL/OGR>} ws]uJ=@րRB s6%km?upkHA~Qbl$E E#w!IENDB`linphone-desktop-4.2.5/linphone-app/assets/icons/hicolor/256x256/000077500000000000000000000000001376717241300244275ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/assets/icons/hicolor/256x256/apps/000077500000000000000000000000001376717241300253725ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/assets/icons/hicolor/256x256/apps/icon.png000066400000000000000000000171001376717241300270270ustar00rootroot00000000000000PNG  IHDR\rfsBIT|d pHYsbb8ztEXtSoftwarewww.inkscape.org<IDATxyua\@d@7@1l1ɫ1Aq!4J|cKTJ\qkDDQ@ͅQAvYǠS9aCuuս4ї l9^Ъ=JtKp@עU JoR,)fNFWS 9y)@l PBEAOkW6 Tc)N`<жB4V `P؍UzֶMJ4j\+}s)jN#;0_ vWzŀEBdfvE>ЅWG+2qf+ã-mWotRiPEO'!\J1`ۦSXB_~BrhVS]4J͟?W}<#lu*Q ?8BxE۝c#l!D6}3敾ж@C/GKЉkB}-e3t!D)AVBq4,e!Lec!LP-Ѕc!LЅE;-d!ʒ/IaRBx& IaRBx& IaRBx& IaRBx& IaRBx& IaRBx3 Seݱ'e$?{ZxcXEJ`v*\!F($8jt ]|u8p*64N:6MȄ "|ҕ{}-}-"8[rJ;cw郯K_νuծ@;)-$7.#$}L[O/Р7&IxuЩk"ˆ/lVAӑБj_}Lbջ$ faν8%:^sB6c%G0N헮$gX&NzӑD\[~SxcΩ$}D߾]Wd# T0/Ek%6i GזN$õ`tRM^G|[wwlOs=OhXGBݷbN%H,Nl޿ $# \\7wPfCjiwwlKS\HhflImDg[L4W@xΞ}"GHU;1~ %_Kq%}b:'(uq?S[A?y~HD*H Җ +ޡI$o:~>K~ʍԽ[b?iVqG§o?y&ڴtOp}<6.I,狾 >W^'El?{w8Lq5v?*jėMs7ڰQgvqL'"D^+s'7rB䤈VqJɍK}_5u{ѥg -R֘!9av1ELb3u>){f:JsNMid巢 tSke1DY6$faWP8yTts\5敦c y*E*lk:JwD:7PELGy,'=+Zc/*`:JNdJb 3Cdݡat4%gybr1St4TL<[5 Hy -]w=(9dz}W.zk L{o#6_h"KGMwS<]j}"ï&tOM.o<(;D1r @w C,S*hm:q.Щ}dvҿ[3%l؇G9LzFM0ʓBy eMGG݂~cd~_ȿ>|6Р!rK§7o'{ҺXp_a=tTG _#L9HC\|YJ,,&Z,PGU)Q4hXި_D؝{vEbO@9c Ϝ<1x}G!Z=a<1u  q.K_=!Z WBKL8W@X֋:*4Pm'ͫT9gP%;^NN -RP׳pj+qjؐ6"E_`~geXO~t{LxeXJm[Cdڝ>X**d*sM˳3\w:`3:Ջ^ܸS/}zd vUwBG\,&pYi 5/\5{ΡΙץ?<_fg[$8nZ{AGkvIآesG«٭k茦OO߻_>(2ȩDlDg?mM;l E׾:REu[fuPem_>9m;$ݾG+ǩJ-xgA;iٯAߨ`*)_} w?L뻷{DݙC{8ǜ2vwNzLH~6'm|eC)*sI,}3#1Us!˷ft6-'i9oj}>g}:!rb&hEAb$.a+ߥ (9e+Wn8Wo3"lc%x9p,-N%H,A|ėNCl3O_ː *3N1EGLq2#Q#ŗI?(ʵ_Ucϣ`̣u7uMf?KY_u2"ꞻ !%љ1rTQL),rZt}='2B B3Ϛ9RHY`:EN:R뗘9RYT7!'9@L),ӱZr)!!jf\:t*R-ץ/Îwh|ծ;68I_Lr_%bHd vǞ:|$v^X]K:[0:VSr͟ڸ%6.AGv}Rnaw*U*@ P0XvReW)t"@j; rrb(ζ/q}i:ar#& IaRBx t6ML@HG m:p.s?,+9ϣB-^za0oI$V1'#\W5 Љ#OƙXm$Z #(]e$?hQ;ؓ_!p(áD,gO/bکLjJ2}ėVb x,Q*hCѵ/7rBm;`re$v)"unJ,{Sb _lPx"r @WMWS(8Bd(c( L*Ҩm|{C(Ox8Jn]LpXJ:P2a6iwOsIA^mHωzO)r*hC_r~/5ĩpp@䭿6k{aJ&'p̹iJ%Eu -#|5Y{bG|ܺ!i]rDE|ҲOx#S!4x *T}X7Dؖ:O$L+muKᘩv)WCKXE=ȿ~Jo[Nx ~{yfW|J&}ݦkwԖ(Y<,}N'4rG筻͡*n:U) py^vC| bNA¶w)c[cE u/ܜcO@ ovBƏTn$6ibEjU!}$8{?S_AG2~\u@ RY;frr&6kvŲ> {n֟xbN1s  S⟼FH]d$C8r R#1RSZJɤ(hr#%HIbջj_|R]9 ϓ mwͦ5U9Yfsr-n:iMj +%j65qיN<so]10֦S&:Qjg:1-Eϧ޴{ųJrk\Ԧrvd_C|>8|woSIx߮[ն%ZЍ<:%eUWSTz}~=T Va:zbwF=j j!^2(O@褫ȿϦc85[qj+u8u tRIHѩ8$$tPv|~P!V~+T^)*V~)Va;T{P]i:q/P]="$e5ZQƳ xd Sd$8r:0EdTڰt!Srꞽt aVaZߐEtDt a!3$,0Cd2NRߕQ H}$"S"8'S)[8_Q=y$NQDXy}t |꿞S[a:Ȁ`( Kttfnc7c785 M4 c:QR(~1UwDj*QD!M0F _Q$t&*THc#HILGiRMPD^=7g;h|3)u/Jl5F4SУ)|U $}QD3_r@84", Z(#xuR⤨{q"Uw i4uY9 HP{Vt&gΙJńTOI2k,ڝz9,52)hYSp2h$/~υQ*锑?75z磀@Ns&av6%9uD^wZ}0ᓯ!|uipS *n:]IbM2R}!;؜^-!]x J\=GW }iɡ,r/eNL>qXy%3 ]ۛ#3n$KQ@3%O6{?-!*TDhXB']ϳ̩JtDg>NӤ+V 7@ko՚̳}=IWv4\;[$c9զ+S#8?ؤ}z9O9Y!v^]Jb1'mrM'H~17kUr-!6:Aj.Cr@.|{D>h O^%6YgUT^)!vJzNp2rDO#t=A)ө5ɍHxwH٥ʛ8z!c1f!Ub83ZUAkνQ}mڸWXofV\H;E/cEe@Kg;s=n8ViTq{FU*߀SןZ)uڼi}:Yc0AGcũLd_UMG8)S"Ψ6X%R(1tG *Cf)tLg. O aRBx& IaRBx& IaRBx& IaRBx& IaRBx& IaRBxfB# tBtV5c! ЪB-s! PzjBJR,7C}bS6D}:lu2>5FUJti٤D-~t!D|3-x`DBlٺs@שD5L6I &wZۇ|DSPn." }D@)Tio6IJj UqǁtMA3/צclʮ?R}cݕBPEK&,]S]DŽ ,r4:{іe]g&d>"Ӕ&~ ^_khícuCfb !2OvJ}mnTJ$ha4Z)uSCsWG;\%Ֆe]]Po,$ '݆Τ -Պܺ㿆O0[_"rﳄtyr%F?GDf_~'_ ,JmYdo;7UY7zuxE7GwѲʺKfƽXK'qr[a:&n?.GJ ?7;uͺĎ%L7"-)lUUG`z5u y?~–_l97@O 6߃y#/#LN|3 8 k oQ8^fȪ[鞇*tv;~aZ5֋1BAtɡ+ 5Ӷ156@_v|. <}~=>BfS%JfS7x`A +`I ֥!..#dL(+#ݛks6Z#NM}E^~MMR~J _)u:nZm L:AŸg\2#LT{(;cZ 0o^Kw9==3-oJKy3wRSاZ}3أc/!DJ43FhYD^#w\nŘ%'vpNjJ@/bYvZ$@!-v2Hn;&E#'*HVd;J.B IҮ֧Qd_u_Vd!"MI32^EiŸ-u@?ƜYZU qR_F˜̍q.dvkXe7N1g) soYӵդMid|Z30.[R{dczvUJhL쿇vr'NZ~f P  OĻN0A LD Z_!dv!Mz:AFQ)9مZ& r?KDur:-UZE~~M} D_J@UǑمdo%g[=,20Bb-mdoԣ!%:Y<1f-1x6{BN=dpCڲU%V<5'[4}O3۝szE\7Ki +ޒVϨU`m<}{Nƒ B" 3kƼ2+#\ɇ2gtD჏m(*(*z *vr953|0̄>Lߎ1k1ƼVr%\z5#~mfW ǕFRs*pݫO q#ar$/ ^}pnU|R*&Pstt aamf*ik{/5v[x1"X>B?#ϽM;I!Qǎh-ļxoS0Q }XG#֧ϼ5r?!1߁oq%7g`tMyS8*܏{΄R?! /ʮLS4q-6n%t|5yPR &kɅ^jNt!hH'F҆{ԥD  B꩔_ Wv%5ַ@nJ+x1JA [X䅡)0\ƭlIENDB`linphone-desktop-4.2.5/linphone-app/assets/images/000077500000000000000000000000001376717241300221615ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/assets/images/add_disabled.svg000066400000000000000000000045221376717241300252640ustar00rootroot00000000000000 image/svg+xml add_disabled add_disabled Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/add_hovered.svg000066400000000000000000000045051376717241300251520ustar00rootroot00000000000000 image/svg+xml add_over add_over Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/add_normal.svg000066400000000000000000000045151376717241300250070ustar00rootroot00000000000000 image/svg+xml add_default add_default Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/add_pressed.svg000066400000000000000000000045531376717241300251660ustar00rootroot00000000000000 image/svg+xml add_clic add_clic Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/attachment_disabled.svg000066400000000000000000000053501376717241300266640ustar00rootroot00000000000000 image/svg+xml attachment_clic attachment_clic Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/attachment_hovered.svg000066400000000000000000000053611376717241300265530ustar00rootroot00000000000000 image/svg+xml attachment_over attachment_over Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/attachment_normal.svg000066400000000000000000000053571376717241300264140ustar00rootroot00000000000000 image/svg+xml attachment_default attachment_default Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/attachment_pressed.svg000066400000000000000000000054031376717241300265610ustar00rootroot00000000000000 image/svg+xml attachment_clic attachment_clic Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/auto_answer.svg000066400000000000000000000045161376717241300252370ustar00rootroot00000000000000 image/svg+xml auto_answer_active auto_answer_active Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/burger_menu_hovered.svg000066400000000000000000000045221376717241300267330ustar00rootroot00000000000000 image/svg+xml burger_menu_over_dark burger_menu_over_dark burger_menu_over_dark Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/burger_menu_light_hovered.svg000066400000000000000000000044351376717241300301250ustar00rootroot00000000000000 image/svg+xml burger_menu_over_bright burger_menu_over_bright Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/burger_menu_light_normal.svg000066400000000000000000000044201376717241300277530ustar00rootroot00000000000000 image/svg+xml burger_menu_default burger_menu_default Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/burger_menu_light_pressed.svg000066400000000000000000000044211376717241300301310ustar00rootroot00000000000000 image/svg+xml burger_menu_default burger_menu_default Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/burger_menu_normal.svg000066400000000000000000000044121376717241300265650ustar00rootroot00000000000000 image/svg+xml burger_menu_default burger_menu_default Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/burger_menu_pressed.svg000066400000000000000000000044131376717241300267430ustar00rootroot00000000000000 image/svg+xml burger_menu_default burger_menu_default Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/call_accept_hovered.svg000066400000000000000000000022521376717241300266510ustar00rootroot00000000000000 call_accept_over Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/call_accept_normal.svg000066400000000000000000000022601376717241300265040ustar00rootroot00000000000000 call_accept default Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/call_accept_pressed.svg000066400000000000000000000022521376717241300266620ustar00rootroot00000000000000 call_accept_clic Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/call_chat_secure_hovered.svg000066400000000000000000000045051376717241300277020ustar00rootroot00000000000000 image/svg+xml chat_secure@x2 chat_secure@x2 Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/call_chat_secure_normal.svg000066400000000000000000000045041376717241300275350ustar00rootroot00000000000000 image/svg+xml chat_secure@x2 chat_secure@x2 Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/call_chat_secure_pressed.svg000066400000000000000000000045051376717241300277130ustar00rootroot00000000000000 image/svg+xml chat_secure@x2 chat_secure@x2 Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/call_chat_unsecure_hovered.svg000066400000000000000000000046551376717241300302530ustar00rootroot00000000000000 image/svg+xml chat_unsecure@x2 chat_unsecure@x2 Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/call_chat_unsecure_normal.svg000066400000000000000000000046541376717241300301060ustar00rootroot00000000000000 image/svg+xml chat_unsecure@x2 chat_unsecure@x2 Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/call_chat_unsecure_pressed.svg000066400000000000000000000046551376717241300302640ustar00rootroot00000000000000 image/svg+xml chat_unsecure@x2 chat_unsecure@x2 Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/call_hovered.svg000066400000000000000000000022361376717241300253340ustar00rootroot00000000000000 call_over Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/call_normal.svg000066400000000000000000000022441376717241300251670ustar00rootroot00000000000000 call_default Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/call_pressed.svg000066400000000000000000000022631376717241300253450ustar00rootroot00000000000000 call_clic Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/call_quality_0.svg000066400000000000000000000045221376717241300256070ustar00rootroot00000000000000 image/svg+xml call_quality_0 call_quality_0 Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/call_quality_1.svg000066400000000000000000000044431376717241300256120ustar00rootroot00000000000000 image/svg+xml call_quality_1 call_quality_1 Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/call_quality_2.svg000066400000000000000000000044431376717241300256130ustar00rootroot00000000000000 image/svg+xml call_quality_2 call_quality_2 Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/call_quality_3.svg000066400000000000000000000043221376717241300256100ustar00rootroot00000000000000 image/svg+xml call_quality_3 call_quality_3 Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/call_sign_connected.svg000066400000000000000000000020461376717241300266610ustar00rootroot00000000000000 call_in_sign Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/call_sign_ended.svg000066400000000000000000000020221376717241300257700ustar00rootroot00000000000000 call_in_sign Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/call_sign_incoming.svg000066400000000000000000000017771376717241300265340ustar00rootroot00000000000000 call_incoming_sign Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/call_sign_outgoing.svg000066400000000000000000000017701376717241300265550ustar00rootroot00000000000000 call_outgoing_sign Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/call_sign_paused.svg000066400000000000000000000013541376717241300262010ustar00rootroot00000000000000 call_pausing_sign Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/camera.svg000066400000000000000000000033421376717241300241340ustar00rootroot00000000000000 image/svg+xml linphone-desktop-4.2.5/linphone-app/assets/images/camera_off_hovered.svg000066400000000000000000000051751376717241300265100ustar00rootroot00000000000000 image/svg+xml camera_off camera_off Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/camera_off_normal.svg000066400000000000000000000051571376717241300263440ustar00rootroot00000000000000 image/svg+xml camera_off camera_off Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/camera_off_pressed.svg000066400000000000000000000052351376717241300265160ustar00rootroot00000000000000 image/svg+xml camera_off_clic camera_off_clic Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/camera_off_updating.svg000066400000000000000000000051611376717241300266620ustar00rootroot00000000000000 image/svg+xml camera_off camera_off Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/camera_on_hovered.svg000066400000000000000000000016521376717241300263460ustar00rootroot00000000000000 camera_on Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/camera_on_normal.svg000066400000000000000000000016511376717241300262010ustar00rootroot00000000000000 camera_on Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/camera_on_pressed.svg000066400000000000000000000017101376717241300263520ustar00rootroot00000000000000 camera_on_clic Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/camera_on_updating.svg000066400000000000000000000016511376717241300265240ustar00rootroot00000000000000 camera_on Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/cancel_hovered.svg000066400000000000000000000025251376717241300256470ustar00rootroot00000000000000 cancel_add_conference_over Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/cancel_normal.svg000066400000000000000000000025331376717241300255020ustar00rootroot00000000000000 cancel_add_conference_default Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/cancel_pressed.svg000066400000000000000000000025521376717241300256600ustar00rootroot00000000000000 cancel_add_conference_clic Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/chat_amount.svg000066400000000000000000000022761376717241300252130ustar00rootroot00000000000000 statut_avatar_busy_l Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/chat_count.svg000066400000000000000000000022751376717241300250370ustar00rootroot00000000000000 chat_count Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/chat_delivered.svg000066400000000000000000000047611376717241300256540ustar00rootroot00000000000000 image/svg+xml chat_delivered chat_delivered Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/chat_error.svg000066400000000000000000000047641376717241300250450ustar00rootroot00000000000000 image/svg+xml chat_error chat_error Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/chat_hovered.svg000066400000000000000000000030121376717241300253310ustar00rootroot00000000000000 chat_over Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/chat_is_composing_0.svg000066400000000000000000000024221376717241300266110ustar00rootroot00000000000000 chat_in_writing_0 Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/chat_is_composing_1.svg000066400000000000000000000024221376717241300266120ustar00rootroot00000000000000 chat_in_writing_1 Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/chat_is_composing_2.svg000066400000000000000000000024221376717241300266130ustar00rootroot00000000000000 chat_in_writing_2 Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/chat_is_composing_3.svg000066400000000000000000000024221376717241300266140ustar00rootroot00000000000000 chat_in_writing_3 Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/chat_normal.svg000066400000000000000000000030201376717241300251640ustar00rootroot00000000000000 chat_default Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/chat_pressed.svg000066400000000000000000000030371376717241300253510ustar00rootroot00000000000000 chat_clic Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/chat_read.svg000066400000000000000000000047731376717241300246270ustar00rootroot00000000000000 image/svg+xml chat_read chat_read Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/collapse.svg000066400000000000000000000044351376717241300245120ustar00rootroot00000000000000 window_close Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/contact_add.svg000066400000000000000000000055701376717241300251540ustar00rootroot00000000000000 image/svg+xml contact_add_default contact_add_default Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/contact_add_hovered.svg000066400000000000000000000055061376717241300266670ustar00rootroot00000000000000 image/svg+xml contact_add_over contact_add_over Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/contact_add_normal.svg000066400000000000000000000055771376717241300265330ustar00rootroot00000000000000 image/svg+xml contact_add_default contact_add_default Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/contact_add_pressed.svg000066400000000000000000000055441376717241300267020ustar00rootroot00000000000000 image/svg+xml contact_add_clic contact_add_clic Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/contact_card_photo_disabled.svg000066400000000000000000000054771376717241300304030ustar00rootroot00000000000000 contact_card_photo_default Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/contact_card_photo_hovered.svg000066400000000000000000000054711376717241300302620ustar00rootroot00000000000000 contact_card_photo_over Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/contact_card_photo_normal.svg000066400000000000000000000054771376717241300301240ustar00rootroot00000000000000 contact_card_photo_default Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/contact_card_photo_pressed.svg000066400000000000000000000055171376717241300302740ustar00rootroot00000000000000 contact_card_photo_over Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/contact_edit_hovered.svg000066400000000000000000000056771376717241300270750ustar00rootroot00000000000000 image/svg+xml contact_edit_over contact_edit_over Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/contact_edit_normal.svg000066400000000000000000000060121376717241300267110ustar00rootroot00000000000000 image/svg+xml contact_edit_default contact_edit_default Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/contact_edit_pressed.svg000066400000000000000000000057171376717241300271010ustar00rootroot00000000000000 image/svg+xml contact_edit_clic contact_edit_clic Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/contact_normal.svg000066400000000000000000000076141376717241300257150ustar00rootroot00000000000000 contact_default Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/contact_selected.svg000066400000000000000000000076001376717241300262100ustar00rootroot00000000000000 contact_selected Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/declined_incoming_call.svg000066400000000000000000000042621376717241300273330ustar00rootroot00000000000000 image/svg+xml call_lost call_lost Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/declined_outgoing_call.svg000066400000000000000000000042621376717241300273630ustar00rootroot00000000000000 image/svg+xml call_lost call_lost Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/delete_hovered.svg000066400000000000000000000043421376717241300256630ustar00rootroot00000000000000 image/svg+xml delete_over delete_over Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/delete_normal.svg000066400000000000000000000043521376717241300255200ustar00rootroot00000000000000 image/svg+xml delete_default delete_default Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/delete_pressed.svg000066400000000000000000000043771376717241300257040ustar00rootroot00000000000000 image/svg+xml delete_clic delete_clic Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/download.svg000066400000000000000000000065341376717241300245210ustar00rootroot00000000000000 dowanload_icon Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/drop_down.svg000066400000000000000000000041221376717241300246740ustar00rootroot00000000000000 image/svg+xml drop_down_list drop_down_list Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/edit_hovered.svg000066400000000000000000000043571376717241300253540ustar00rootroot00000000000000 image/svg+xml settings_edit_default settings_edit_default Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/edit_normal.svg000066400000000000000000000043561376717241300252070ustar00rootroot00000000000000 image/svg+xml settings_edit_default settings_edit_default Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/edit_pressed.svg000066400000000000000000000044151376717241300253600ustar00rootroot00000000000000 image/svg+xml settings_edit_default settings_edit_default Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/ended_call.svg000066400000000000000000000046341376717241300247630ustar00rootroot00000000000000 image/svg+xml call_end call_end Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/file_hovered.svg000066400000000000000000000055001376717241300253350ustar00rootroot00000000000000 image/svg+xml settings_file_1 settings_file_1 Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/file_normal.svg000066400000000000000000000051551376717241300251770ustar00rootroot00000000000000 image/svg+xml settings_file_3 settings_file_3 Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/file_pressed.svg000066400000000000000000000052141376717241300253500ustar00rootroot00000000000000 image/svg+xml settings_file_2 settings_file_2 Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/file_sign.svg000066400000000000000000000033401376717241300246410ustar00rootroot00000000000000 download_ended Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/filter.svg000066400000000000000000000012561376717241300241730ustar00rootroot00000000000000 filter Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/folder_hovered.svg000066400000000000000000000045441376717241300257000ustar00rootroot00000000000000 image/svg+xml settings_folder_1 settings_folder_1 Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/folder_normal.svg000066400000000000000000000045431376717241300255330ustar00rootroot00000000000000 image/svg+xml settings_folder_3 settings_folder_3 Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/folder_pressed.svg000066400000000000000000000046021376717241300257040ustar00rootroot00000000000000 image/svg+xml settings_folder_2 settings_folder_2 Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/fullscreen_hovered.svg000066400000000000000000000025611376717241300265640ustar00rootroot00000000000000 fullscreen_over Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/fullscreen_normal.svg000066400000000000000000000025111376717241300264130ustar00rootroot00000000000000 fullscreen_default Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/fullscreen_pressed.svg000066400000000000000000000025611376717241300265750ustar00rootroot00000000000000 fullscreen_over Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/generic_error.svg000066400000000000000000000044551376717241300255370ustar00rootroot00000000000000 image/svg+xml chat_error chat_error Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/generic_error_hovered.svg000066400000000000000000000044651376717241300272540ustar00rootroot00000000000000 image/svg+xml chat_error chat_error Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/generic_error_normal.svg000066400000000000000000000044641376717241300271070ustar00rootroot00000000000000 image/svg+xml chat_error chat_error Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/generic_error_pressed.svg000066400000000000000000000044651376717241300272650ustar00rootroot00000000000000 image/svg+xml chat_error chat_error Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/hangup_hovered.svg000066400000000000000000000023471376717241300257060ustar00rootroot00000000000000 hangup_over Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/hangup_normal.svg000066400000000000000000000023541376717241300255400ustar00rootroot00000000000000 hangup_default Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/hangup_pressed.svg000066400000000000000000000023461376717241300257160ustar00rootroot00000000000000 hangup_clic Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/history.svg000066400000000000000000000014301376717241300244010ustar00rootroot00000000000000 history Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/history_hovered.svg000066400000000000000000000017521376717241300261240ustar00rootroot00000000000000 history_over Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/history_normal.svg000066400000000000000000000017601376717241300257570ustar00rootroot00000000000000 history_default Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/history_pressed.svg000066400000000000000000000017771376717241300261440ustar00rootroot00000000000000 history_clic Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/home_account_assistant.svg000066400000000000000000000113451376717241300274430ustar00rootroot00000000000000 image/svg+xml home_account_assistant home_account_assistant Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/home_invite_friends.svg000066400000000000000000000130141376717241300267210ustar00rootroot00000000000000 image/svg+xml home_invite_friends home_invite_friends Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/home_normal.svg000066400000000000000000000023451376717241300252060ustar00rootroot00000000000000 home_icon_default Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/home_selected.svg000066400000000000000000000023311376717241300255010ustar00rootroot00000000000000 home_icon_selected Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/home_use_linphone.svg000066400000000000000000000105131376717241300264020ustar00rootroot00000000000000 image/svg+xml home_use_linphone home_use_linphone Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/incoming_call.svg000066400000000000000000000042041376717241300255000ustar00rootroot00000000000000 image/svg+xml call_incoming call_incoming Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/led_green.svg000066400000000000000000000021771376717241300246350ustar00rootroot00000000000000 statut_avatar_available_l Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/led_orange.svg000066400000000000000000000021711376717241300250020ustar00rootroot00000000000000 statut_avatar_absent_l Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/led_red.svg000066400000000000000000000022511376717241300243000ustar00rootroot00000000000000 statut_avatar_busy_l Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/led_white.svg000066400000000000000000000022051376717241300246450ustar00rootroot00000000000000 statut_avatar_disconnected_l Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/linphone_logo.svg000066400000000000000000000725671376717241300255570ustar00rootroot00000000000000 image/svg+xml linphone-desktop-4.2.5/linphone-app/assets/images/message_sign.svg000066400000000000000000000033071376717241300253510ustar00rootroot00000000000000 call_sms_sign Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/micro.svg000066400000000000000000000036761376717241300240270ustar00rootroot00000000000000 image/svg+xml linphone-desktop-4.2.5/linphone-app/assets/images/micro_off_hovered.svg000066400000000000000000000027731376717241300263720ustar00rootroot00000000000000 micro_off Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/micro_off_normal.svg000066400000000000000000000027731376717241300262260ustar00rootroot00000000000000 micro_off Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/micro_off_pressed.svg000066400000000000000000000030311376717241300263670ustar00rootroot00000000000000 micro_off_clic Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/micro_on_hovered.svg000066400000000000000000000027021376717241300262240ustar00rootroot00000000000000 micro_on Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/micro_on_normal.svg000066400000000000000000000027011376717241300260570ustar00rootroot00000000000000 micro_on Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/micro_on_pressed.svg000066400000000000000000000027401376717241300262370ustar00rootroot00000000000000 micro_on_clic Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/missed_incoming_call.svg000066400000000000000000000042621376717241300270500ustar00rootroot00000000000000 image/svg+xml call_lost call_lost Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/missed_outgoing_call.svg000066400000000000000000000042621376717241300271000ustar00rootroot00000000000000 image/svg+xml call_lost call_lost Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/new_call_hovered.svg000066400000000000000000000027231376717241300262060ustar00rootroot00000000000000 new_call_clic Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/new_call_normal.svg000066400000000000000000000030601376717241300260350ustar00rootroot00000000000000 new_call_default Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/new_call_pressed.svg000066400000000000000000000030601376717241300262120ustar00rootroot00000000000000 new_call_default Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/new_conference_hovered.svg000066400000000000000000000061071376717241300274020ustar00rootroot00000000000000 new_conference_clic Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/new_conference_normal.svg000066400000000000000000000061151376717241300272350ustar00rootroot00000000000000 new_conference_default Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/new_conference_pressed.svg000066400000000000000000000061141376717241300274110ustar00rootroot00000000000000 new_conference_default Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/options_hovered.svg000066400000000000000000000041731376717241300261160ustar00rootroot00000000000000 options_over Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/options_normal.svg000066400000000000000000000042011376717241300257420ustar00rootroot00000000000000 options_default Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/options_pressed.svg000066400000000000000000000042201376717241300261200ustar00rootroot00000000000000 options_clic Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/outgoing_call.svg000066400000000000000000000042161376717241300255330ustar00rootroot00000000000000 image/svg+xml call_outgoing call_outgoing Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/pause_off_hovered.svg000066400000000000000000000014571376717241300263740ustar00rootroot00000000000000 play_over Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/pause_off_normal.svg000066400000000000000000000014651376717241300262270ustar00rootroot00000000000000 play_default Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/pause_off_pressed.svg000066400000000000000000000015041376717241300263760ustar00rootroot00000000000000 play_clic Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/pause_off_updating.svg000066400000000000000000000014651376717241300265520ustar00rootroot00000000000000 play_default Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/pause_on_hovered.svg000066400000000000000000000014721376717241300262330ustar00rootroot00000000000000 pause_over Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/pause_on_normal.svg000066400000000000000000000015001376717241300260570ustar00rootroot00000000000000 pause_default Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/pause_on_pressed.svg000066400000000000000000000015171376717241300262440ustar00rootroot00000000000000 pause_clic Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/pause_on_updating.svg000066400000000000000000000015001376717241300264020ustar00rootroot00000000000000 pause_default Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/record_off.svg000066400000000000000000000070001376717241300250070ustar00rootroot00000000000000 record_default Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/record_on.svg000066400000000000000000000070731376717241300246630ustar00rootroot00000000000000 record_over Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/recording_sign.svg000066400000000000000000000040621376717241300257000ustar00rootroot00000000000000 image/svg+xml linphone-desktop-4.2.5/linphone-app/assets/images/screenshot_hovered.svg000066400000000000000000000037351376717241300266030ustar00rootroot00000000000000 screenshot_over Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/screenshot_normal.svg000066400000000000000000000035021376717241300264270ustar00rootroot00000000000000 screenshot_default Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/screenshot_pressed.svg000066400000000000000000000037351376717241300266140ustar00rootroot00000000000000 screenshot_over Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/search.svg000066400000000000000000000045501376717241300241530ustar00rootroot00000000000000 search Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/settings_advanced_normal.svg000066400000000000000000000040741376717241300277440ustar00rootroot00000000000000 settings_advanced_default Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/settings_advanced_selected.svg000066400000000000000000000041251376717241300302410ustar00rootroot00000000000000 settings_advanced_selected Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/settings_audio_normal.svg000066400000000000000000000044111376717241300272730ustar00rootroot00000000000000 image/svg+xml settings_audio_default settings_audio_default Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/settings_audio_selected.svg000066400000000000000000000044731376717241300276030ustar00rootroot00000000000000 image/svg+xml settings_audio_selected settings_audio_selected Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/settings_call_normal.svg000066400000000000000000000017721376717241300271140ustar00rootroot00000000000000 settings_call_default Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/settings_call_selected.svg000066400000000000000000000020231376717241300274020ustar00rootroot00000000000000 settings_call_selected Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/settings_network_normal.svg000066400000000000000000000132551376717241300276710ustar00rootroot00000000000000 image/svg+xml settings_network_default settings_network_default Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/settings_network_selected.svg000066400000000000000000000133161376717241300301670ustar00rootroot00000000000000 image/svg+xml settings_network_selected settings_network_selected Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/settings_sip_accounts_normal.svg000066400000000000000000000052261376717241300306710ustar00rootroot00000000000000 image/svg+xml settings_account_default settings_account_default Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/settings_sip_accounts_selected.svg000066400000000000000000000052621376717241300311710ustar00rootroot00000000000000 image/svg+xml settings_account_selected settings_account_selected Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/settings_video_normal.svg000066400000000000000000000042051376717241300273010ustar00rootroot00000000000000 image/svg+xml settings_video_default settings_video_default Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/settings_video_selected.svg000066400000000000000000000042531376717241300276040ustar00rootroot00000000000000 image/svg+xml settings_video_selected settings_video_selected Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/snapshot_sign.svg000066400000000000000000000067211376717241300255670ustar00rootroot00000000000000 image/svg+xml linphone-desktop-4.2.5/linphone-app/assets/images/speaker.svg000066400000000000000000000034201376717241300243330ustar00rootroot00000000000000 image/svg+xml linphone-desktop-4.2.5/linphone-app/assets/images/speaker_off_hovered.svg000066400000000000000000000024311376717241300267020ustar00rootroot00000000000000 speaker_off Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/speaker_off_normal.svg000066400000000000000000000024311376717241300265360ustar00rootroot00000000000000 speaker_off Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/speaker_off_pressed.svg000066400000000000000000000024671376717241300267240ustar00rootroot00000000000000 speaker_off_clic Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/speaker_on_hovered.svg000066400000000000000000000021571376717241300265510ustar00rootroot00000000000000 speaker_on Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/speaker_on_normal.svg000066400000000000000000000021561376717241300264040ustar00rootroot00000000000000 speaker_on Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/speaker_on_pressed.svg000066400000000000000000000022151376717241300265550ustar00rootroot00000000000000 speaker_on_clic Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/tel_keypad_hovered.svg000066400000000000000000000073651376717241300265520ustar00rootroot00000000000000 image/svg+xml dialer_dtmf dialer_dtmf Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/tel_keypad_normal.svg000066400000000000000000000073331376717241300264010ustar00rootroot00000000000000 image/svg+xml dialer_dtmf dialer_dtmf Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/tel_keypad_pressed.svg000066400000000000000000000073701376717241300265570ustar00rootroot00000000000000 image/svg+xml dialer_dtmf dialer_dtmf Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/timeline_history.svg000066400000000000000000000014311376717241300262700ustar00rootroot00000000000000 history Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/tooltip_arrow_bottom.svg000066400000000000000000000036301376717241300271740ustar00rootroot00000000000000 image/svg+xml tooltip tooltip Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/tooltip_arrow_left.svg000066400000000000000000000035371376717241300266300ustar00rootroot00000000000000 image/svg+xml tooltip tooltip Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/tooltip_arrow_right.svg000066400000000000000000000035761376717241300270160ustar00rootroot00000000000000 image/svg+xml tooltip tooltip Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/tooltip_arrow_top.svg000066400000000000000000000035661376717241300265020ustar00rootroot00000000000000 image/svg+xml tooltip tooltip Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/transfer_hovered.svg000066400000000000000000000026031376717241300262430ustar00rootroot00000000000000 transfer_over Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/transfer_normal.svg000066400000000000000000000026071376717241300261030ustar00rootroot00000000000000 transfer_default Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/transfer_pressed.svg000066400000000000000000000026301376717241300262540ustar00rootroot00000000000000 transfer_clic Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/update_sign.svg000066400000000000000000000111071376717241300252040ustar00rootroot00000000000000 image/svg+xml download_ended Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/video_call_accept_hovered.svg000066400000000000000000000021361376717241300300400ustar00rootroot00000000000000 video_call_accept_over Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/video_call_accept_normal.svg000066400000000000000000000021441376717241300276730ustar00rootroot00000000000000 video_call_accept_default Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/video_call_accept_pressed.svg000066400000000000000000000021361376717241300300510ustar00rootroot00000000000000 video_call_accept_clic Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/video_call_hovered.svg000066400000000000000000000021221376717241300265140ustar00rootroot00000000000000 video_call_over Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/video_call_normal.svg000066400000000000000000000021301376717241300263470ustar00rootroot00000000000000 video_call_default Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/video_call_pressed.svg000066400000000000000000000021501376717241300265260ustar00rootroot00000000000000 video_call_clic Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/images/warning.svg000066400000000000000000000047641376717241300243620ustar00rootroot00000000000000 image/svg+xml chat_error chat_error Created with Sketch. linphone-desktop-4.2.5/linphone-app/assets/languages/000077500000000000000000000000001376717241300226625ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/assets/languages/CMakeLists.txt000066400000000000000000000061741376717241300254320ustar00rootroot00000000000000# ============================================================================== # assets/languages/CMakeLists.txt # ============================================================================== # This line prevent `.ts` files deletion. # See: https://bugreports.qt.io/browse/QTBUG-31860 # # On October 17, 2016, this issue was marked `invalid` but it's a # bullshit. It's not tolerated to remove source files. set_directory_properties(PROPERTIES CLEAN_NO_CUSTOM true) # Build languages resource file. set(TS_FILES) set(QM_FILES) set(QM_FILES_OUTPUT_DIR "${CMAKE_CURRENT_BINARY_DIR}") set(I18N_CONTENT "\n\n \n") foreach (lang ${LANGUAGES}) # Note: the below `languages/` path is not the same as the `${LANGUAGES_DIRECTORY}` value. # It's the symbolic path used by the linphone binary in the qrc model. # This path is used in `app.cpp`. set(I18N_CONTENT "${I18N_CONTENT} ${lang}.qm\n") list(APPEND TS_FILES "${CMAKE_CURRENT_SOURCE_DIR}/${lang}.ts") list(APPEND TARGET_TS_FILES "${CMAKE_CURRENT_BINARY_DIR}/${lang}.ts") list(APPEND QM_FILES "${CMAKE_CURRENT_BINARY_DIR}/${lang}.qm") endforeach() set(I18N_CONTENT "${I18N_CONTENT} \n\n") file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/${I18N_FILENAME}" "${I18N_CONTENT}") #Files or directories to inspect for translations references set(TRANSLATION_SOURCES) list(APPEND TRANSLATION_SOURCES "${PROJECT_SOURCE_DIR}/src") list(APPEND TRANSLATION_SOURCES "${PROJECT_SOURCE_DIR}/ui") if (WIN32) foreach (lang ${LANGUAGES}) file(READ "${CMAKE_CURRENT_SOURCE_DIR}/${lang}.ts" content) set(cleanedContent) string(REPLACE "\r" "" cleanedContent "${content}") file(WRITE "${CMAKE_CURRENT_SOURCE_DIR}/${lang}.ts" "${cleanedContent}") endforeach() endif() set(LUPDATE_OPTIONS "-no-obsolete") set(LRELEASE_OPTIONS "") #Clean existing generated file to force re-creation file(REMOVE ${QM_FILES}) file(REMOVE ${TARGET_TS_FILES}) #file(REMOVE ${QRC_BIG_RESOURCES}) #Remove .o of resources before build. It is need to update resources from changes add_custom_command(OUTPUT ${TARGET_TS_FILES} COMMAND ${Qt5_LUPDATE_EXECUTABLE} ARGS ${LUPDATE_OPTIONS} ${TRANSLATION_SOURCES} -ts ${TS_FILES} COMMAND ${CMAKE_COMMAND} -E copy ${TS_FILES} ${CMAKE_CURRENT_BINARY_DIR} VERBATIM WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} COMMENT "Updating translation source files (ts)..." ) add_custom_command(OUTPUT ${QM_FILES} COMMAND ${Qt5_LRELEASE_EXECUTABLE} ARGS ${TARGET_TS_FILES} ${LRELEASE_OPTIONS} DEPENDS ${TARGET_TS_FILES} WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} VERBATIM COMMENT "Creating compiled translation files (qm)..." ) #The dependency on custom_command Output is important add_custom_target(update_translations DEPENDS ${QM_FILES} ) # Remove `*.qm` when `clean` is called. set_directory_properties(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES "${QM_FILES}") # Workaround: Create empty files for some cmake versions. Otherwise, the qm rules can't be used. # foreach (qm ${QM_FILES}) # if (NOT EXISTS "${qm}") # file(GENERATE OUTPUT "${qm}" CONTENT "") # endif() # endforeach() linphone-desktop-4.2.5/linphone-app/assets/languages/da.ts000066400000000000000000002413161376717241300236250ustar00rootroot00000000000000 About ok OK ActivateAppSipAccountWithEmail activateAppSipAccount AKTIVER DIN %1 KONTO confirmAction AKTIVER activationSteps For at aktivere din konto, følg vejledningen sendt til %1 og klik hernede ActivateAppSipAccountWithPhoneNumber activateAppSipAccount AKTIVER DIN %1 KONTO confirmAction AKTIVER activationSteps Vi har sendt en SMS med valideringskoden til %1. For at kunne fuldføre valideringen, indtast den 4-cifrede kode hernede App commandLineOptionVerbose log til stdout nogle debug informationer under kørslen commandLineOptionConfig vælg %1 konfigurationsfilen der skal bruges applicationDescription En gratis SIP video telefon commandLineOptionIconified start i systemets bakke, vis ikke hovedvinduet commandLineOptionConfigArg fil commandLineOptionHelp vis denne hjælp commandLineOptionVersion vis app versionen commandLineOptionCliHelp vis hjælpemenu for at bruge %1 med CLI commandLineDescription send en ordre til applikationen mod en kommandolinje restore Gendan quit Luk settings Indstillinger about Om AssistantAbstractView back TILBAGE AssistantHome useAppSipAccount BRUG EN %1 KONTO useOtherSipAccount BRUG EN SIP KONTO fetchRemoteConfiguration HENT FJERN KONFIGURATION homeTitle VELKOMMEN homeDescription Assistenten vil hjælpe dig med konfigurationen af din sip konto createAppSipAccount OPRET EN %1 KONTO AssistantModel loginWithUsernameFailed Fejl ved log ind. Tjek dit brugernavn eller kodeord. usernameStatusTooShort For kort! (%1 tegn min.) usernameStatusTooLong For lang! (%1 tegn maks.) usernameStatusInvalidCharacters Ugyldig tegn. (regex: `%1`) usernameStatusInvalid Forkert brugernavn. passwordStatusTooShort For kort! (%1 tegn min.) passwordStatusTooLong For lang! (%1 tegn maks.) passwordStatusInvalidCharacters Ugyldig tegn. (regex: `%1`) passwordStatusMissingCharacters Manglende tegn: `%1`. requestFailed Umuligt at sende anmodningen. emailStatusMalformed Ugyldig e-mailadresse. emailStatusMalformedInvalidCharacters Ugyldig e-mailadresse eller tegn. cannotSendSms Serverfejl: umuligt at sende sms. accountAlreadyExists Kontoen findes allerede. smsActivationFailed Fejlet SMS aktivering! emailActivationFailed Tjek at du har valideret din konto eller prøv igen. phoneNumberStatusInvalid Ugyldig telefonnummer! phoneNumberStatusTooShort For kort! phoneNumberStatusTooLong For lang! phoneNumberStatusInvalidCountryCode Forkert landekode! loginWithPhoneNumberFailed Fejl ved log ind. Tjek dit telefonnummer. unableToAddAccount Umuligt at oprette kontoen. AuthenticationRequest cancel ANNULLER confirm LOG IND identityLabel Identitet passwordLabel Kodeord authenticationRequestDescription Fejl ved log ind. Tjek dit kodeord. userIdLabel Bruger ID (valgfrit) realmLabel Realm CallModel callStatsCodec Codec callStatsUploadBandwidth Båndbredde for upload callStatsDownloadBandwidth Båndbredde for download callStatsEstimatedDownloadBandwidth Estimeret båndbredde for download callStatsIceState ICE status callStatsIpFamily IP familie callStatsSenderLossRate Senders tab hastighed callStatsReceiverLossRate Modtagers tab hastighed callStatsJitterBuffer Jitter buffer callStatsSentVideoDefinition Sendt video opløsning callStatsReceivedVideoDefinition Modtaget video opløsning iceStateNotActivated Deaktiveret iceStateFailed Fejlet iceStateInProgress I gang iceStateReflexiveConnection Refleksiv forbindelse iceStateHostConnection Host forbindelse iceStateRelayConnection Relay forbindelse iceStateInvalid Ugyldig callErrorDeclined Fjern part afviste opkaldet. callErrorNotFound Fjern part blev ikke fundet. callErrorBusy Fjern part er optaget. callErrorNotAcceptable Fjern part can ikke modtage opkaldet. callStatsReceivedFramerate Modtaget hastighed callStatsSentFramerate Sendt hastighed CallSipAddress cancel ANNULLER callSipAddressDescription Start et nyt opkald. CallStatistics audioStatsLabel Audio videoStatsLabel Video CallTransfer cancel ANNULLER callTransferDescription Vil du overføre dette opkald? Calls acceptAudioCall BESVAR AUDIO OPKALD acceptVideoCall BESVAR VIDEO OPKALD terminateCall LÆG RØR PÅ resumeCall FORTSÆT OPKALDET transferCall OVERFØR OPKALDET callPause PAUSE OPKALDET CallsWindow callsTitle Opkald acceptClosingDescription Er du sikker på at du vil afbryde alle opkald? Chat newMessagePlaceholder Indtast din besked noFileTransferUrl Fejl ved fil overførsel. Server url ikke konfigureret. isComposing %1 indtaster... Cli appCliDescription Styr %1 applikationen ved hjælp af kommandolinje. uriCommandLineSyntax %1 <sip-address>?method=<method>([&<argument>=<base64-value>]*) cliCommandLineSyntax %1" <method>([<argument>=<value>]*)" commandsName kommandoliste: showFunctionDescription vis applikationens hovedvinduet. callFunctionDescription Start et opkald til sip-adresse. initiateConferenceFunctionDescription Start en konference. joinConferenceFunctionDescription Deltag i konferencen startet af sip-adressen som navnet viser. Hvis du er forbundet til en proxy, se "deltag konferencen som". joinConferenceAsFunctionDescription Deltag i konferencen startet af sip-adressen som har gæstens sip-adresse. Hvis du ikke er forbundet til en proxy, se "deltag konferencen". CodecsViewer codecMime Navn codecEncoderDescription Beskrivelse codecEncoderClockRate Frekvens (Hz) codecBitrate Hastighed (Kbit/s) codecRecvFmtp Parametre codecStatus Status Conference conferenceTitle KONFERENCE ConferenceControls conference KONFERENCE ConferenceManager conferenceManagerDescription Vælg deltagere til din konference. cancel ANNULLER confirm START ConfirmDialog cancel ANNULLER confirm BEKRÆFT ContactEdit removeContactDescription Er du sikker på at du vil fjerne denne kontakt fra din telefonbog? sipAccounts SIP KONTI address ADRESSE emails E-MAILADRESSER webSites WEBSIDER avatarChooserTitle Vælg din avatar companies FIRMAER save GEM cancel ANNULLER sipAccountsPlaceholder SIP konto companiesPlaceholder Firma emailsPlaceholder E-mailadresse webSitesPlaceholder Webside street Vej postalCode Postnummer country Land locality Sted abortEditDescriptionText Er du sikker på at du vil annullere ændringen? tooltipShowConversation Vis samtale Contacts searchContactPlaceholder Søg kontakt selectAllContacts Alle selectConnectedContacts Forbundet addContact OPRET KONTAKT removeContactDescription Er du sikker på at du vil fjerne denne kontakt fra din telefonbog? Conversation displayCallsAndMessages ALLE displayCalls OPKALD displayMessages BESKEDER removeAllEntriesDescription Er du sikker på at du vil rydde op historikken? tooltipContactEdit Rediger kontakt tooltipContactAdd Tilføj kontakt cleanHistory Slet historik CreateAppSipAccount createAppSipAccountDescription Hvordan vil du oprette din konto? createAppSipAccountTitle OPRET EN %1 KONTO withPhoneNumber MED ET TELEFONNUMMER withEmailAddress MED EN E-MAILADRESSE CreateAppSipAccountWithEmail createAppSipAccountTitle OPRET EN %1 KONTO confirmAction OPRET usernameLabel Brugernavn emailLabel E-mailadresse passwordLabel Kodeord passwordConfirmationLabel Bekræft kodeordet passwordConfirmationError Kodeordet du har indtastet matcher ikke. quitWarning Din konto er blevet oprettet men endnu ikke valideret. Er du sikker på at du vil lukke denne dialogboks? displayNameLabel Navn til visning (valgfrit) CreateAppSipAccountWithPhoneNumber createAppSipAccountTitle OPRET EN %1 KONTO countryLabel Land phoneNumberLabel Telefonnummer usernameLabel Brugernavn displayNameLabel Navn til visning (valgfrit) confirmAction OPRET quitWarning Din konto er blevet oprettet men endnu ikke valideret. Hvis du lukker denne dialogboks skal du indtaste og validere din konto indenfor 24 timer. DroppableTextArea fileChooserTitle Vælg en eller flere filer dropYourAttachment Slip din vedhæftet fil attachmentTooltip Send en fil Event incomingCall Indgående opkald outgoingCall Udgående opkald declinedIncomingCall Afvist indgående opkald declinedOutgoingCall Afvist udgående opkald endedCall Afsluttet opkald missedIncomingCall Tabt indgående opkald missedOutgoingCall Tabt udgående opkald FetchRemoteConfiguration confirmAction HENT fetchRemoteConfigurationTitle HENT FJERN KONFIGURATION urlLabel URL remoteProvisioningError Umuligt at gemme denne fjern konfigurations uri. remoteProvisioningUpdateDescription Det er nødvendigt at genstarte applikationen. Vil du gøre det nu? HistoryView removeAllEntriesDescription Er du sikker på at du vil rydde op historikken? tooltipContactEdit Rediger kontakt tooltipContactAdd Tilføj kontakt cleanHistory Slet historik Home howToDescription Har du behov for hjælp for at bruge %1? howToTitle HVORDAN MAN BRUGER %1 inviteDescription Inviter dine venner på %1. inviteTitle INVITER DINE VENNER accountAssistantDescription Opret eller ret din %1 konto. accountAssistantTitle KONTO ASSISTENT assistantButton ASSISTENT showTooltips Vis tips inviteButton INVITER Incall acceptVideoDescription Din kontakt vil skifte til video. pendingRequestLabel Vent, en anmodning er i gang. securedStringFormat Opkaldet er krypteret med: %1. callNotSecured Opkaldet er ikke krypteret. takeSnapshotLabel Tag en snapshot. startRecordingLabel Start optagelsen. stopRecordingLabel Stop optagelsen. IncallFullscreenWindow takeSnapshotLabel Tag en snapshot. startRecordingLabel Start optagelsen. stopRecordingLabel Stop optagelsen. InviteFriends enterEmailLabel Din vens e-mailadresse messageLabel Besked cancel ANNULLER confirm BEKRÆFT inviteFriendsTitle Inviter dine venner defaultMessage %1 inviterer dig på %2! defaultSubject %1 invitation forcedMessage Hent applikationen på din computer og start samtaler eller chat med venner gratis. Klik her: <a href="%1">%1</a> MainWindow mainSearchBarPlaceholder Søg en kontakt, start en samtale eller en chat... homeEntry HJEM contactsEntry KONTAKTER autoAnswerStatus auto smartSearchBarTooltip Brug den smarte søgefunktion for at starte audio og video opkald, sende en besked eller oprette en ny kontakt. Indtast din vens SIP-adresse eller brugernavn. newConferenceButton Start konferenceopkald MainWindowMenuBar settings Indstillinger about Om quit Luk MainWindowTopMenuBar settings Præferencer about Om quit Stop ManageAccounts ok OK selectPresenceLabel Status selectAccountLabel Aktiv konto Message menuCopy Kopier menuPlayMe Afspil mig! MultimediaParameters ok OK Notifier newVersionAvailable En ny version (%1) er tilgængelig! newFileMessage Modtaget ny vedhæftet fil! OnlineInstallerDialog confirm BEKRÆFT onlineInstallerExtractingDescription Åbning %1... onlineInstallerDownloadingDescription Downloading %1... onlineInstallerFinishedDescription %1 er nu installeret! onlineInstallerFailedDescription Fejl ved installationen af %1! OutgoingMessage messageError Fejl messageRead Læs messageDelivered Afleveret Presence presenceOnline Tilgængelig presenceBusy Optaget presenceDoNotDisturb Forstyr ikke presenceOffline Offline SettingsAdvanced logsTitle Logs logsFolderLabel Logs folder sendLogs SEND LOGS logsUploadUrlLabel Server URL for uploading af logs logsUploadFailed Fejl ved log uploading. logsEnabledLabel Aktiver logs cleanLogs NUSTIL LOGS cleanLogsDescription Er du sikker på at du vil fjerne alle logs? developerSettingsTitle Udvikler indstillinger developerSettingsEnabledLabel Aktiver udvikler indstillinger logsMailerFailed Message when Linphone try to open a mailer to send logs, after uploading them to the server (%1 would be the upload url) Mailer kan ikke findes men logfiler blev uploadet til %1 logsMailerSuccess Logfiler blev uploadet til %1 SettingsAudio audioTitle Audio parametre playbackDeviceLabel Afspilnings udstyr captureDeviceLabel Optagelses udstyr ringerDeviceLabel Klokkes udstyr ringLabel Klokke echoCancellationLabel Aktiver echo annullering audioCodecsTitle Audio codecs showAudioCodecsLabel Vis audio codecs playbackGainLabel Afspilning forstærkning captureGainLabel Capture gevinst audioTestLabel Optagelsesniveau audioSettingsInCallWarning Lydopkald i gang: Nogle indstillinger er ikke tilgængelige. SettingsCallsChat fileServerLabel Filserver encryptWithLimeLabel Krypter med LIME limeDisabled Deaktiveret limeRequired Påkravet limePreferred Foretrukket chatTitle Chat callsTitle Opkald encryptionLabel Kryptering noEncryption Ingen autoAnswerLabel Autosvar autoAnswerDelayLabel Forsinkelse (ms) autoAnswerWithVideoLabel Autosvar (med video) chatEnabledLabel Aktiver chat callRecorderEnabledLabel Aktiver opkalds optagelse chatNotificationSoundEnabledLabel Aktiver advarsels ringetone chatNotificationSoundLabel Advarsels ringetone conferenceEnabledLabel Aktiver konference contactsTitle Kontakter contactsEnabledLabel Aktiver kontakter muteMicrophoneEnabledLabel Mute mikrofon outgoingCallsEnabledLabel Aktiver udgående opkald showTelKeypadAutomaticallyLabel Vis telefonens tastatur automatisk automaticallyRecordCallsLabel Optag opkald automatisk keepCallsWindowInBackgroundLabel Sæt opkaldets vindue i baggrund callPauseEnabledLabel Aktiver pause på opkald encryptionMandatoryLabel Krydning er obligatorisk SettingsNetwork sendDtmfsLabel DTMFs afsendelses måde allowIpV6Label Tillad IPv6 transportTitle Transport natAndFirewallTitle NAT og firewall enableIceLabel Aktiver ICE stunServerLabel STUN/TURN server enableTurnLabel Aktiver TURN turnUserLabel TURNs bruger turnPasswordLabel TURNs kodeord networkProtocolAndPortsTitle Netværks protokol og porte sipUdpPortLabel SIP UDP port sipTcpPortLabel SIP TCP port audioRtpUdpPortLabel Audio RTP UDP port videoRtpUdpPortLabel Video RTP UDP port dscpFieldsTitle DSCP felter sipFieldLabel SIP audioRtpStreamFieldLabel Audio RTP stream videoRtpStreamFieldLabel Video RTP stream bandwidthControlTitle Båndbredde kontrol downloadSpeedLimitLabel Download hastigheds begrænsning i Kbit/sek uploadSpeedLimitLabel Upload hastigheds begrænsning i Kbit/sek enableAdaptiveRateControlLabel Aktiver tilpasset hastigheds kontrol presenceTitle Presence rlsUriLabel Brug RLS URI rlsUriAuto AUTO rlsUriDisabled ALDRIG showNetworkSettingsLabel Vis netværks indstillinger generalTitle Generelt SettingsSipAccounts defaultIdentityTitle Standards identitet defaultUsernameLabel Brugernavn defaultSipAddressLabel SIP-adresse proxyAccountsTitle Proxy konti eraseAllPasswords NUSTIL KODEORD addAccount OPRET KONTO editHeader Rediger deleteHeader Slet deleteAccountDescription Er du sikker på at du vil slette denne konto? eraseAllPasswordsDescription Er du sikker på at du vil slette alle kodeord? defaultDisplayNameLabel Navn til visning assistantTitle Assistent createAppSipAccountEnabledLabel Aktiver konto oprettelse useAppSipAccountEnabledLabel Aktiver brug af konto useOtherSipAccountEnabledLabel Aktiver generisk konto brug fetchRemoteConfigurationEnabledLabel Aktiver konfigurations afhentning assistantSupportsPhoneNumbersLabel Understøtter telefonnumre SettingsSipAccountsEdit sipAddressLabel SIP-adresse transportLabel Transport serverAddressLabel SIP server adresse registrationDurationLabel Optagelses varighed (sek) routeLabel Rute contactParamsLabel Kontakt parametre publishPresenceLabel Publicer tilstedeværelses information avpfIntervalLabel AVPF almindelig RTCP interval (sek) registerEnabledLabel Registrer avpfEnabledLabel Aktiver AVPF cancel ANNULLER confirm BEKRÆFT invalidSipAddress Ugyldig SIP-adresse. invalidServerAddress Ugyldig server adresse. invalidRoute Ugyldig rute. enableIceLabel Aktiver ICE stunServerLabel STUN/TURN server enableTurnLabel Aktiver TURN turnUserLabel TURNs bruger turnPasswordLabel TURNs kodeord natAndFirewallTitle NAT og firewall mainSipAccountSettingsTitle SIP konto hovedindstillinger SettingsUi pathsTitle Stier savedScreenshotsLabel Gemte skærmbilleder folder savedCallsLabel Gemte opkald folder languagesTitle Sprog languagesLabel Sprog systemLocale System lokale cleanAvatars SLET AVATARS cleanAvatarsDescription Er du sikker på at du vil slette alle avatars? downloadLabel Download folder setLocaleDescription Det er nødvendigt at genstarte applikationen. Vil du gøre det nu? otherTitle Andet exitOnCloseLabel Luk applikationen ved at lukke vinduet dataTitle UI data autoStartLabel Autostart applikation SettingsVideo videoInputDeviceLabel Video indgang videoFramerateLabel Hastighed videoCaptureTitle Video parametre videoPresetLabel Video forudindstilling presetDefault Standard presetHighFps Høj FPS presetCustom Tilpasset videoSizeLabel Video opløsning videoCodecsTitle Video codecs showCameraPreview VIDEO FORHÅNDSVISNING showVideoCodecsLabel Vis video codecs videoSettingsInCallWarning Videoopkald i gang: Nogle indstillinger er ikke tilgængelige. SettingsVideoPreview confirm OK SettingsWindow settingsTitle Indstillinger sipAccountsTab SIP konti audioTab Audio videoTab Video callsAndChatTab Opkald og chat networkTab Netværk uiTab UI validButton OK uiAdvanced Avanceret SmartSearchBar addContact OPRET KONTAKT Timeline timelineTitle Forrige UseAppSipAccount confirmAction BRUG useAppSipAccountTitle BRUG EN %1 KONTO useUsernameToLogin Brug brugernavn og kodeord frem for dit telefonnummer. quitWarning Din konto er blevet oprettet men endnu ikke valideret. Er du sikker på at du vil lukke denne dialogboks? UseAppSipAccountWithPhoneNumber countryLabel Land phoneNumberLabel Telefonnummer UseAppSipAccountWithUsername usernameLabel Brugernavn passwordLabel Kodeord UseOtherSipAccount confirmAction BRUG useOtherSipAccountTitle BRUG EN SIP KONTO usernameLabel Brugernavn displayNameLabel Navn til visning (valgfrit) sipDomainLabel SIP domænet passwordLabel Kodeord transportLabel Transport addOtherSipAccountError Umuligt at oprette kontoen. ZrtpTokenAuthentication confirmSas Bekræft følgende SAS med peer. codeA Sig: codeB Din kontakt burde sige: deny STOP accept BEKRÆFT country Afghanistan Afghanistan Albania Albanien Algeria Algeriet AmericanSamoa Amerikansk Samoa Andorra Andorra Angola Angola Anguilla Anguilla AntiguaAndBarbuda Antigua og Barbuda Argentina Argentina Armenia Armenien Aruba Aruba Australia Australien Austria Østrig Azerbaijan Aserbajdsjan Bahamas Bahamas Bahrain Bahrain Bangladesh Bangladesh Barbados Barbados Belarus Hviderusland Belgium Belgien Belize Belize Benin Benin Bermuda Bermuda Bhutan Bhutan Bolivia Bolivia BosniaAndHerzegowina Bosnien-Hercegovina Botswana Botswana Brazil Brasilien Brunei Brunei Bulgaria Bulgarien BurkinaFaso Burkina Faso Burundi Burundi Cambodia Cambodja Cameroon Cameroun Canada Canada CapeVerde Kap Verde CaymanIslands Caymanøerne CentralAfricanRepublic Den Centralafrikanske Republik Chad Tchad Chile Chile China Kina Colombia Columbia Comoros Comorerne PeoplesRepublicOfCongo Republikken Congo DemocraticRepublicOfCongo Den Demokratiske Republik Congo CookIslands Cookøerne CostaRica Costa Rica IvoryCoast Elfenbenskysten Croatia Kroatien Cuba Cuba Cyprus Cypern CzechRepublic Tjekkiet Denmark Danmark Djibouti Djibouti Dominica Dominica DominicanRepublic Den Dominikanske Republik Ecuador Ecuador Egypt Ægypten ElSalvador El Salvador EquatorialGuinea Ækvatorialguinea Eritrea Eritrea Estonia Estland Ethiopia Etiopien FalklandIslands Falklandsøerne FaroeIslands Færøerne Fiji Fiji Finland Finland France Frankrig FrenchGuiana Fransk Guyana FrenchPolynesia Fransk Polynesien Gabon Gabon Gambia Gambia Georgia Georgien Germany Tyskland Ghana Ghana Gibraltar Gibraltar Greece Grækenland Greenland Grønland Grenada Grenada Guadeloupe Guadeloupe Guam Guam Guatemala Guatemala Guinea Guinea GuineaBissau Guinea-Bissau Guyana Guyana Haiti Haiti Honduras Honduras HongKong Hongkong Hungary Ungarn Iceland Island India Indien Indonesia Indonesien Iran Iran Iraq Irak Ireland Irland Israel Israel Italy Italien Jamaica Jamaica Japan Japan Jordan Jordan Kazakhstan Kasakhstan Kenya Kenya Kiribati Kiribati DemocraticRepublicOfKorea Den Demokratiske Republik Korea RepublicOfKorea Republikken Korea Kuwait Kuwait Kyrgyzstan Kirgisistan Laos Laos Latvia Letland Lebanon Libanon Lesotho Lesotho Liberia Liberia Libya Libyen Liechtenstein Liechtenstein Lithuania Litauen Luxembourg Luxembourg Macau Macao Macedonia Makedonien Madagascar Madagaskar Malawi Malawi Malaysia Malaysia Maldives Maldiverne Mali Mali Malta Malta MarshallIslands Marshalløerne Martinique Martinique Mauritania Mauretanien Mauritius Mauritius Mayotte Mayotte Mexico Mexico Micronesia Mikronesien Moldova Moldova Monaco Monaco Mongolia Mongoliet Montenegro Montenegro Montserrat Montserrat Morocco Marokko Mozambique Mozambique Myanmar Myanmar Namibia Namibia NauruCountry Nauru Nepal Nepal Netherlands Nederlandene NewCaledonia Ny Kaledonien NewZealand New Zealand Nicaragua Nicaragua Niger Niger Nigeria Nigeria Niue Niue NorfolkIsland Norfolk Island NorthernMarianaIslands Nordmarianerne Norway Norge Oman Oman Pakistan Pakistan Palau Palau PalestinianTerritories Palæstinensiske områder Panama Panama PapuaNewGuinea Papua Ny Guinea Paraguay Paraguay Peru Peru Philippines Filippinerne Poland Polen Portugal Portugal PuertoRico Puerto Rico Qatar Qatar Reunion Genforening Romania Rumænien RussianFederation Den Russiske Føderation Rwanda Rwanda SaintHelena Saint Helena SaintKittsAndNevis Saint Kitts Og Nevis SaintLucia Saint Lucia SaintPierreAndMiquelon Saint Pierre og Miquelon SaintVincentAndTheGrenadines Saint Vincent Og Grenadinerne Samoa Samoa SanMarino San Marino SaoTomeAndPrincipe São Tomé Og Principe SaudiArabia Saudi-Arabien Senegal Senegal Serbia Serbien Seychelles Seychellerne SierraLeone Sierra Leone Singapore Singapore Slovakia Slovakiet Slovenia Slovenien SolomonIslands Salomonøerne Somalia Somalia SouthAfrica Sydafrika Spain Spanien SriLanka Sri Lanka Sudan Sudan Suriname Surinam Swaziland Swaziland Sweden Sverige Switzerland Schweiz Syria Syrien Taiwan Taiwan Tajikistan Tadsjikistan Tanzania Tanzania Thailand Thailand Togo Togo Tokelau Tokelau Tonga Tonga TrinidadAndTobago Trinidad Og Tobago Tunisia Tunesien Turkey Tyrkiet Turkmenistan Turkmenistan TurksAndCaicosIslands Turks- og Caicosøerne Tuvalu Tuvalu Uganda Uganda Ukraine Ukraine UnitedArabEmirates Forenede Arabiske Emirater UnitedKingdom Det Forenede Kongerige UnitedStates USA Uruguay Uruguay Uzbekistan Usbekistan Vanuatu Vanuatu Venezuela Venezuela Vietnam Vietnam WallisAndFutunaIslands Wallis og Futunaøerne Yemen Yemen Zambia Zambia Zimbabwe - Zimbabwe linphone-utils downloadCodecDescription Vil du downloade %1 (%2)? linphone-desktop-4.2.5/linphone-app/assets/languages/de.ts000066400000000000000000002445301376717241300236320ustar00rootroot00000000000000 About ok OK ActivateAppSipAccountWithEmail activateAppSipAccount AKTIVIEREN SIE IHR %1 KONTO confirmAction AKTIVIEREN activationSteps Um Ihr Konto zu aktivieren, folgen Sie den Anweisungen, die wir an %1 gesendet haben. Anschließend klicken Sie hier: ActivateAppSipAccountWithPhoneNumber activateAppSipAccount AKTIVIEREN SIE IHR %1-KONTO confirmAction AKTIVIEREN activationSteps Wir haben eine SMS mit einem Validierungs-Code an %1 gesendet. Um die Verifizierung der Telefonnummer abzuschließen, geben Sie bitten den 4-stelligen Code unten ein. App commandLineOptionVerbose Während der Verwendung nach stdout debug informationen ausgeben commandLineOptionConfig Bitte zu verwendende Konfigration angeben applicationDescription Ein freies (gratis) Video-Telefon commandLineOptionIconified Im Systemtray starten, Hauptmenü nicht anzeigen commandLineOptionConfigArg Datei commandLineOptionHelp Diese Hilfe anzeigen commandLineOptionVersion App-Version anzeigen commandLineOptionCliHelp zeigt das Hilfe-Menü zur Kommandozeilen-Schnittstelle von %1 commandLineDescription sende einen Befehl zur Anwendung für eine Kommandozeile restore Wiederherstellen quit Schließen settings Einstellungen about Über AssistantAbstractView back ZURÜCK AssistantHome useAppSipAccount %1-KONTO VERWENDEN useOtherSipAccount SIP-KONTO VERWENDEN fetchRemoteConfiguration FERNKONFIGRATION LADEN homeTitle WILLKOMMEN homeDescription Der Assistent hilft Ihnen das %1 Konto zu konfigurieren und zu nutzen createAppSipAccount %1-KONTO ERSTELLEN AssistantModel loginWithUsernameFailed Login fehlgeschlagen. Bitte überprüfen Sie Ihren Benutzernamen und das Passwort. usernameStatusTooShort Zu kurz (mindestens %1 Zeichen) usernameStatusTooLong Zu lang (maximal %1 Zeichen) usernameStatusInvalidCharacters Ungültige Zeichen gefunden. (regex: `%1`) usernameStatusInvalid Ungültiger Benutzername. passwordStatusTooShort Zu kurz! (mindestens %1 Zeichen) passwordStatusTooLong Zu lang! (maximal %1 Zeichen) passwordStatusInvalidCharacters Ungültige Zeichen gefunden. (regex: `%1`) passwordStatusMissingCharacters Fehlende Zeichen: `%1`. requestFailed Das Senden der Anfrage ist fehlgeschlagen. emailStatusMalformed Falsche E-Mail-Adresse. emailStatusMalformedInvalidCharacters Falsche E-Mail-Adresse oder ungültige Zeichen. cannotSendSms Server-Fehler: SMS konnte nicht versendet werden. accountAlreadyExists Dieses Konto existiert bereits. smsActivationFailed SMS-Aktivierung fehlgeschlagen! emailActivationFailed Bitte vergewissern Sie sich, dass Sie ihr Konto verifiziert haben oder versuchen Sie es erneut. phoneNumberStatusInvalid Ungültige Telefonnummer! phoneNumberStatusTooShort Zu kurz! phoneNumberStatusTooLong Zu lang! phoneNumberStatusInvalidCountryCode Ungültiger Länder-Code! loginWithPhoneNumberFailed Login fehlgeschlagen. Bitte überprüfen Sie Ihre Telefonnummer. unableToAddAccount Dieses Konto kann nicht hinzugefügt werden. AuthenticationRequest cancel ABBRECHEN confirm ANMELDEN identityLabel Identität passwordLabel Passwort authenticationRequestDescription Authentifizierung fehlgeschlagen. Bitte überprüfen Sie Ihr Passwort. userIdLabel Benutzerkennung (optional) realmLabel Realm CallModel callStatsCodec Codec callStatsUploadBandwidth Upload-Bandbreite callStatsDownloadBandwidth Download-Bandbreite callStatsEstimatedDownloadBandwidth Geschätzte Download-Bandbreite callStatsIceState ICE Status callStatsIpFamily IP-Familie callStatsSenderLossRate Sender Verlustrate callStatsReceiverLossRate Empfänger Verlustrate callStatsJitterBuffer Jitter Puffer callStatsSentVideoDefinition Gesendete Video-Definition callStatsReceivedVideoDefinition Empfangene Video-Definition iceStateNotActivated Nicht aktiviert iceStateFailed Fehlgeschlagen iceStateInProgress In Arbeit iceStateReflexiveConnection Reflexive Verbindung iceStateHostConnection Host Verbindung iceStateRelayConnection Relay Verbindung iceStateInvalid Ungültig callErrorDeclined Gegenstelle hat den Anruf abgelehnt. callErrorNotFound Gegenstelle wurde nicht gefunden. callErrorBusy Gegenstelle ist besetzt. callErrorNotAcceptable Die Gegenstelle kann den Anruf nicht annehmen. callStatsReceivedFramerate Erhaltene Framerate callStatsSentFramerate Gesendete Framerate CallSipAddress cancel ABBRECHEN callSipAddressDescription Einen neuen Anruf starten. CallStatistics audioStatsLabel Audio videoStatsLabel Video CallTransfer cancel ABBRECHEN callTransferDescription Möchten Sie diesen Anruf weiterleiten? Calls acceptAudioCall AUDIO-ANRUF ANNEHMEN acceptVideoCall VIDEO-ANRUF ANNEHMEN terminateCall AUFLEGEN resumeCall ANRUF FORTSETZEN transferCall ANRUF WEITERLEITEN callPause ANRUF PAUSIEREN CallsWindow callsTitle Anrufe acceptClosingDescription Sind Sie sicher, dass sie alle Anrufe beenden möchten? Chat newMessagePlaceholder Geben Sie ihre Nachricht ein. noFileTransferUrl Datei kann nicht gesendet werden. Server URL ist nicht konfiguriert. isComposing %1 schreibt gerade... Cli appCliDescription Methode um die %1 Anwendung per Kommandozeile zu steuern. uriCommandLineSyntax %1 <sip-address>?method=<method>([&<argument>=<base64-value>]*) cliCommandLineSyntax %1 "<method> ([<argument>=<value>]*)" commandsName Kommandoliste : showFunctionDescription Zeigt das Hauptfenster der Anwendung. callFunctionDescription Initiiere Anruf zur SIP-Adresse. initiateConferenceFunctionDescription Initiiere eine Konferenz. joinConferenceFunctionDescription Tritt der Konferenz auf dem Host sip-address als display-name bei. Wenn Sie über einen Proxy verbunden sind beachten Sie join-conference-as joinConferenceAsFunctionDescription Tritt der Konferenz auf dem Host sip-address als guest-sip-address bei. Wenn Sie nicht über einen Proxy verbunden sind beachten Sie join-conference CodecsViewer codecMime Name codecEncoderDescription Beschreibung codecEncoderClockRate Rate (Hz) codecBitrate Bitrate (Kbit/s) codecRecvFmtp Parameter codecStatus Status Conference conferenceTitle KONFERENZ ConferenceControls conference KONFERENZ ConferenceManager conferenceManagerDescription Verwalten Sie die Teilnehmer Ihrer Konferenz. cancel ABBRECHEN confirm START ConfirmDialog cancel ABBRECHEN confirm BESTÄTIGEN ContactEdit removeContactDescription Möchten Sie wirklich diesen Kontakt aus Ihrem Adressbuch entfernen? sipAccounts SIP-KONTEN address ADRESSE emails E-MAIL(S) webSites WEBSEITE(N) avatarChooserTitle Wählen Sie ihr Avatar. companies UNTERNEHMEN save SPEICHERN cancel ABBRECHEN sipAccountsPlaceholder SIP Konto companiesPlaceholder Unternehmen emailsPlaceholder Email webSitesPlaceholder Webseite street Straße postalCode Postleitzahl country Land locality Ort abortEditDescriptionText Möchten Sie die Änderungen an diesem Kontakt verwerfen? tooltipShowConversation Konversation anzeigen Contacts searchContactPlaceholder Suche Kontakt selectAllContacts Alle selectConnectedContacts Verbunden addContact KONTAKT HINZUFÜGEN removeContactDescription Möchten sie diesen Kontakt wirklich aus Ihrem Adressbuch löschen? Conversation displayCallsAndMessages ALLE displayCalls ANRUFE displayMessages NACHRICHTEN removeAllEntriesDescription Möchten Sie diese Historie wirklich löschen? tooltipContactEdit Kontakt bearbeiten tooltipContactAdd Kontakt hinzufügen cleanHistory Verlauf löschen CreateAppSipAccount createAppSipAccountDescription Wie würden Sie gerne Ihr Konto erstellen? createAppSipAccountTitle ERSTELLE EIN %1 KONTO withPhoneNumber MIT EINER TELEFONNUMMER withEmailAddress MIT EINER E-MAIL-ADRESSE CreateAppSipAccountWithEmail createAppSipAccountTitle %1-KONTO ERSTELLEN confirmAction ERSTELLEN usernameLabel Benutzername emailLabel Email passwordLabel Passwort passwordConfirmationLabel Passwortbestätigung passwordConfirmationError Die eingegebenen Passwörter stimmen nicht überein. quitWarning Ihr Konto wurde erstellt, jedoch noch nicht aktiviert. Sind Sie sicher, dass Sie diese Ansicht verlassen möchten? displayNameLabel Anzeigename (optional) CreateAppSipAccountWithPhoneNumber createAppSipAccountTitle %1-KONTO ERSTELLEN countryLabel Land phoneNumberLabel Telefonnummer usernameLabel Benutzername displayNameLabel Anzeigename (optional) confirmAction ERSTELLEN quitWarning Ihr Konto wurde erstellt aber noch nicht verifiziert. Wenn Sie diese Ansicht schließen müssen Sie Ihr Konto innerhalb der nächsten 24 Stunden manuell anlegen und verifizieren. DroppableTextArea fileChooserTitle Bitte wählen Sie eine oder mehrere Dateien dropYourAttachment Anhang fallen lassen. attachmentTooltip Datei senden Event incomingCall Eingehender Anruf outgoingCall Ausgehender Anruf declinedIncomingCall Abgelehnter eingehender Anruf declinedOutgoingCall Abgelehnter ausgehender Anruf endedCall Abgebrochener Anruf missedIncomingCall Verpasster eingehender Anruf missedOutgoingCall Verpasster ausgehender Anruf FetchRemoteConfiguration confirmAction ABRUFEN fetchRemoteConfigurationTitle HOLE REMOTE-KONFIGURATION urlLabel URL remoteProvisioningError Es ist nicht möglich, diese Fernkonfigrations-URL zu verwenden. remoteProvisioningUpdateDescription Ein Neustart der Anwendung ist notwendig. Möchten Sie die Anwendung jetzt neu starten? HistoryView removeAllEntriesDescription Möchten Sie diese Historie wirklich löschen? tooltipContactEdit Kontakt bearbeiten tooltipContactAdd Kontakt hinzufügen cleanHistory Verlauf löschen Home howToDescription Benötigen Sie hilfe um linephone zu nutzen? howToTitle WIE MAN %1 NUTZT inviteDescription Laden Sie Ihre Freunde bei %1 ein. inviteTitle FREUNDE EINLADEN accountAssistantDescription Erstellen oder verwalten Sie ihr %1 Konto. accountAssistantTitle KONTOASSISTENT assistantButton ASSISTENT showTooltips Zeige Tooltips inviteButton EINLADEN Incall acceptVideoDescription Ihr Kontakt würde gerne die Videoübertragung aktivieren. pendingRequestLabel Bitte warten, Anfrage wird verarbeitet. securedStringFormat Anruf ist verschlüsselt mit: %1. callNotSecured Anruf nicht verschlüsselt. takeSnapshotLabel Schnappschuss machen. startRecordingLabel Aufnahme starten. stopRecordingLabel Aufnahme stoppen. IncallFullscreenWindow takeSnapshotLabel Schnappschuss machen. startRecordingLabel Aufnahme starten. stopRecordingLabel Aufnahme stoppen. InviteFriends enterEmailLabel Email Adresse des Freundes messageLabel Nachricht cancel ABBRECHEN confirm BESTÄTIGEN inviteFriendsTitle Freunde einladen defaultMessage %1 möchte Sie bei %2 einladen ! defaultSubject %1-Einladung forcedMessage Laden Sie die Anwendung auf Ihren Computer um kostenlos mit anderen Linphone Benutzern zu telefonieren und zu chatten. Klicken Sie hier: <a href="%1">%1</a> MainWindow mainSearchBarPlaceholder Suche Kontakte, starte einen Anruf oder Chat... homeEntry HOME contactsEntry KONTAKTE autoAnswerStatus automatisch smartSearchBarTooltip Verwenden das intelligente Suchfeld um Audio- und Videocalls zu starten, Nachrichten zu senden oder Kontakt hinzuzufügen. Geben Sie die SIP-Adresse oder Username Ihres Kontaktes ein. newConferenceButton Telefonkonferenz starten MainWindowMenuBar settings Einstellungen about Über quit Schließen MainWindowTopMenuBar settings Einstellungen about Über quit Aufhören ManageAccounts ok OK selectPresenceLabel Anwesenheitsstatus selectAccountLabel Aktives Konto Message menuCopy Kopieren menuPlayMe Spiel mich ab! MultimediaParameters ok OK Notifier newVersionAvailable Eine neue Version (%1) ist verfügbar! newFileMessage Neuen Anhang erhalten! OnlineInstallerDialog confirm BESTÄTIGEN onlineInstallerExtractingDescription %1 wird extrahiert... onlineInstallerDownloadingDescription %1 wird heruntergeladen... onlineInstallerFinishedDescription %1 ist jetzt installiert! onlineInstallerFailedDescription Fehler beim installieren, %1! OutgoingMessage messageError Fehler messageRead Lesen messageDelivered Zugestellt Presence presenceOnline Verfügbar presenceBusy Besetzt presenceDoNotDisturb Nicht stören presenceOffline Offline SettingsAdvanced logsTitle Protokolle logsFolderLabel Protokolleordner sendLogs PROTOKOLLE SENDEN logsUploadUrlLabel Server URL für Log-Upload logsUploadFailed Logs konnten nicht hochgeladen werden. logsEnabledLabel Protokolle aktiviert cleanLogs PROTOKOLLE BEREINIGEN cleanLogsDescription Sind Sie sicher, dass sie alle Logs löschen möchten? developerSettingsTitle Entwicklereinstellungen developerSettingsEnabledLabel Entwicklereinstellungen aktivieren logsMailerFailed Message when Linphone try to open a mailer to send logs, after uploading them to the server (%1 would be the upload url) Mailer kann nicht gefunden werden, Protokolle wurden in %1 hochgeladen logsMailerSuccess Protokolle wurden auf %1 hochgeladen SettingsAudio audioTitle Audioparameter playbackDeviceLabel Wiedergabegerät captureDeviceLabel Aufnahmegerät ringerDeviceLabel Gerät für Anrufgeräusch ringLabel Anrufgeräusch echoCancellationLabel Echounterdrückung aktivieren audioCodecsTitle Audiocodecs showAudioCodecsLabel Zeige Audiocodecs playbackGainLabel Wiedergabe-Verstärkung captureGainLabel Capture Gain audioTestLabel Erfassungsebene audioSettingsInCallWarning Audioanruf wird ausgeführt: Einige Einstellungen sind nicht verfügbar. SettingsCallsChat fileServerLabel Dateiserver encryptWithLimeLabel Mit LIME verschlüsseln limeDisabled Deaktiviert limeRequired Obligatorisch limePreferred Bevorzugt chatTitle Chat callsTitle Anrufe encryptionLabel Verschlüsselung noEncryption Keine autoAnswerLabel Automatische Antwort autoAnswerDelayLabel Verzögerung (in ms) autoAnswerWithVideoLabel Automatische Antwort (mit Video) chatEnabledLabel Chat aktivieren callRecorderEnabledLabel Anrufaufzeichnung aktivieren chatNotificationSoundEnabledLabel Benachrichtigungston aktivieren chatNotificationSoundLabel Benachrichtigungston conferenceEnabledLabel Konferenz aktivieren contactsTitle Kontakte contactsEnabledLabel Kontakte aktivieren muteMicrophoneEnabledLabel Mikrofon-Stummschaltung aktivieren outgoingCallsEnabledLabel Ausgehende Anrufe aktivieren showTelKeypadAutomaticallyLabel Tastenfeld automatisch anzeigen automaticallyRecordCallsLabel Anrufe automatisch aufnehmen keepCallsWindowInBackgroundLabel Anrufe-Fenster im Hintergrund halten callPauseEnabledLabel Anruf pausieren aktiviert encryptionMandatoryLabel Verschlüsselung ist obligatorisch SettingsNetwork sendDtmfsLabel MFV Übertragungsmodus allowIpV6Label IPv6 erlauben transportTitle Transport natAndFirewallTitle NAT und Firewall enableIceLabel ICE aktivieren stunServerLabel STUN/TURN-Server enableTurnLabel TURN aktivieren turnUserLabel TURN-Benutzer turnPasswordLabel TURN-Passwort networkProtocolAndPortsTitle Netzwerkprotokoll und -ports sipUdpPortLabel SIP UDP-Port sipTcpPortLabel SIP TCP-Port audioRtpUdpPortLabel Audio RTP UDP Port videoRtpUdpPortLabel Video RTP UDP Port dscpFieldsTitle DSCP-Felder sipFieldLabel SIP audioRtpStreamFieldLabel Audio RTP Stream videoRtpStreamFieldLabel Video RTP Stream bandwidthControlTitle Bandbreitensteuerung downloadSpeedLimitLabel Downloadgeschwindigkeitslimit in Kbit/sek uploadSpeedLimitLabel Uploadgeschwindigkeitslimit in Kbit/sek enableAdaptiveRateControlLabel Aktiviere adaptive Ratenbegrenzung presenceTitle Anwesenheit rlsUriLabel Benutze RLS URI rlsUriAuto AUTOMATISCH rlsUriDisabled NIE showNetworkSettingsLabel Netzwerkeinstellungen anzeigen generalTitle Allgemein SettingsSipAccounts defaultIdentityTitle Standardidentität defaultUsernameLabel Benutzername defaultSipAddressLabel SIP-Adresse proxyAccountsTitle Proxy Zugänge eraseAllPasswords PASSWÖRTER LÖSCHEN addAccount KONTO HINZUFÜGEN editHeader Bearbeiten deleteHeader Löschen deleteAccountDescription Sind Sie sicher, dass sie dieses Konto löschen möchten? eraseAllPasswordsDescription Sind Sie sicher, dass sie alle Passwörter löschen möchten? defaultDisplayNameLabel Anzeigename assistantTitle Assistent createAppSipAccountEnabledLabel Erstellung eines Benutzerkontos aktivieren useAppSipAccountEnabledLabel Nutzung eines Benutzerkontos aktivieren useOtherSipAccountEnabledLabel Nutzung sonstiger Benutzerkonten aktivieren fetchRemoteConfigurationEnabledLabel Abrufen von Konfigurationsdaten aktivieren assistantSupportsPhoneNumbersLabel Telefonnummern werden unterstützt SettingsSipAccountsEdit sipAddressLabel SIP-Adresse transportLabel Transport serverAddressLabel SIP-Serveradresse registrationDurationLabel Registrierungsdauer (Sek.) routeLabel Route contactParamsLabel Kontaktparameter publishPresenceLabel Presence Informationen publizieren. avpfIntervalLabel AVPF regular RTCP interval (Sekunden) registerEnabledLabel Registrieren avpfEnabledLabel AVPF aktivieren cancel ABBRECHEN confirm BESTÄTIGEN invalidSipAddress Ungültige SIP Adresse. invalidServerAddress Ungültige Serveradresse. invalidRoute Ungültige Route. enableIceLabel ICE aktivieren stunServerLabel STUN/TURN Server enableTurnLabel Aktiviere TURN turnUserLabel TURN Benutzer turnPasswordLabel TURN Passwort natAndFirewallTitle NAT und Firewall mainSipAccountSettingsTitle Haupteinstellungen des SIP-Kontos SettingsUi pathsTitle Pfade savedScreenshotsLabel Ordner für gespeicherte Screenshots savedCallsLabel Ordner für gespeicherte Anrufe languagesTitle Sprachen languagesLabel Sprache systemLocale Systemgebietsschema cleanAvatars AVATARE LÖSCHEN cleanAvatarsDescription Sind Sie sicher, dass Sie alle Avatare löschen möchten? downloadLabel Download-Ordner setLocaleDescription Ein Neustart der Anwendung ist notwendig. Möchten Sie die Anwendung jetzt neu starten? otherTitle Anderes exitOnCloseLabel Beende App beim Schließen des Fensters. dataTitle UI-Daten autoStartLabel Anwendung automatisch starten SettingsVideo videoInputDeviceLabel Videoausgabegerät videoFramerateLabel Bildfrequenz videoCaptureTitle Videoaufzeichnungsparameter videoPresetLabel Videovoreinstellungen presetDefault Standard presetHighFps Hohe FPS presetCustom Individuell videoSizeLabel Videoauflösung videoCodecsTitle Videocodecs showCameraPreview VIDEOVORSCHAU showVideoCodecsLabel Zeige Videocodecs videoSettingsInCallWarning Videoanruf wird ausgeführt: Einige Einstellungen sind nicht verfügbar. SettingsVideoPreview confirm OK SettingsWindow settingsTitle Einstellungen sipAccountsTab SIP-Konten audioTab Audio videoTab Video callsAndChatTab Anrufe und Chat networkTab Netzwerk uiTab Benutzeroberfläche validButton OK uiAdvanced Erweitert SmartSearchBar addContact KONTAKT HINZUFÜGEN Timeline timelineTitle Vorherige UseAppSipAccount confirmAction VERWENDEN useAppSipAccountTitle %1-KONTO VERWENDEN useUsernameToLogin Benutzername und Passwort soll nicht gleich sein, wie die Telefonnummer quitWarning Ihr Konto wurde erstellt, aber nicht validiert. Möchten Sie diese Ansicht wirklich verlassen? UseAppSipAccountWithPhoneNumber countryLabel Land phoneNumberLabel Telefonnummer UseAppSipAccountWithUsername usernameLabel Benutzername passwordLabel Passwort UseOtherSipAccount confirmAction VERWENDEN useOtherSipAccountTitle SIP-KONTO VERWENDEN usernameLabel Benutzername displayNameLabel Anzeigename (optional) sipDomainLabel SIP Domäne passwordLabel Passwort transportLabel Transport addOtherSipAccountError Dieses Konto kann nicht hinzugefügt werden. ZrtpTokenAuthentication confirmSas Bestätige folgende SAS mit der Gegenstelle codeA Sagen: codeB Ihr Kontakt sollte sagen: deny ABLEHNEN accept BESTÄTIGEN country Afghanistan Afghanistan Albania Albanien Algeria Algerien AmericanSamoa Amerikanisch-Samoa Andorra Andorra Angola Angola Anguilla Anguilla AntiguaAndBarbuda Antigua und Barbuda Argentina Argentinien Armenia Armenien Aruba Aruba Australia Australien Austria Österreich Azerbaijan Aserbaidschan Bahamas Bahamas Bahrain Bahrain Bangladesh Bangladesch Barbados Barbados Belarus Weißrussland Belgium Belgien Belize Belize Benin Benin Bermuda Bermuda Bhutan Bhutan Bolivia Bolivien BosniaAndHerzegowina Bosnien und Herzegowina Botswana Botsuana Brazil Brasilien Brunei Brunei Bulgaria Bulgarien BurkinaFaso Burkina Faso Burundi Burundi Cambodia Kambodscha Cameroon Kamerun Canada Kanada CapeVerde Kap Verde CaymanIslands Kaimaninseln CentralAfricanRepublic Zentralafrikanische Republik Chad Tschad Chile Chile China China Colombia Kolumbien Comoros Komoren PeoplesRepublicOfCongo Republik Kongo DemocraticRepublicOfCongo Demokratische Republik Kongo CookIslands Cook-Inseln CostaRica Costa Rica IvoryCoast Elfenbeinküste Croatia Kroatien Cuba Kuba Cyprus Zypern CzechRepublic Tschechische Republik Denmark Dänemark Djibouti Dschibuti Dominica Dominica DominicanRepublic Dominikanische Republik Ecuador Ecuador Egypt Ägypten ElSalvador El Salvador EquatorialGuinea Äquatorialguinea Eritrea Eritrea Estonia Estland Ethiopia Äthiopien FalklandIslands Falklandinseln FaroeIslands Färöer Inseln Fiji Fidschi Finland Finnland France Frankreich FrenchGuiana Französisch-Guayana FrenchPolynesia Französisch-Polynesien Gabon Gabun Gambia Gambia Georgia Georgien Germany Deutschland Ghana Ghana Gibraltar Gibraltar Greece Griechenland Greenland Grönland Grenada Grenada Guadeloupe Guadeloupe Guam Guam Guatemala Guatemala Guinea Guinea GuineaBissau Guinea-Bissau Guyana Guyana Haiti Haiti Honduras Honduras HongKong Hong Kong Hungary Ungarn Iceland Island India Indien Indonesia Indonesien Iran Iran Iraq Irak Ireland Irland Israel Israel Italy Italien Jamaica Jamaika Japan Japan Jordan Jordan Kazakhstan Kasachstan Kenya Kenia Kiribati Kiribati DemocraticRepublicOfKorea Demokratische Republik Korea RepublicOfKorea Republik Korea Kuwait Kuwait Kyrgyzstan Kirgisistan Laos Laos Latvia Lettland Lebanon Libanon Lesotho Lesotho Liberia Liberia Libya Libyen Liechtenstein Liechtenstein Lithuania Litauen Luxembourg Luxemburg Macau Macao Macedonia Mazedonien Madagascar Madagaskar Malawi Malawi Malaysia Malaysia Maldives Malediven Mali Mali Malta Malta MarshallIslands Marshallinseln Martinique Martinique Mauritania Mauretanien Mauritius Mauritius Mayotte Mayotte Mexico Mexiko Micronesia Mikronesien Moldova Moldau Monaco Monaco Mongolia Mongolei Montenegro Montenegro Montserrat Montserrat Morocco Marokko Mozambique Mosambik Myanmar Myanmar Namibia Namibia NauruCountry Nauru Nepal Nepal Netherlands Niederlande NewCaledonia Neukaledonien NewZealand Neuseeland Nicaragua Nicaragua Niger Niger Nigeria Nigeria Niue Niue NorfolkIsland Norfolkinsel NorthernMarianaIslands Nördliche Marianen Norway Norwegen Oman Oman Pakistan Pakistan Palau Palau PalestinianTerritories Palästinensische Autonomiegebiete Panama Panama PapuaNewGuinea Papua-Neuguinea Paraguay Paraguay Peru Peru Philippines Philippinen Poland Polen Portugal Portugal PuertoRico Puerto Rico Qatar Katar Reunion Wiedervereinigung Romania Rumänien RussianFederation Russische Föderation Rwanda Ruanda SaintHelena St. Helena SaintKittsAndNevis St. Kitts und Nevis SaintLucia St. Lucia SaintPierreAndMiquelon St. Pierre und Miquelon SaintVincentAndTheGrenadines St. Vincent und die Grenadinen Samoa Samoa SanMarino San Marino SaoTomeAndPrincipe São Tomé und Principe SaudiArabia Saudi-Arabien Senegal Senegal Serbia Serbien Seychelles Seychellen SierraLeone Sierra Leone Singapore Singapur Slovakia Slowakei Slovenia Slowenien SolomonIslands Salomonen Somalia Somalia SouthAfrica Südafrika Spain Spanien SriLanka Sri Lanka Sudan Sudan Suriname Suriname Swaziland Swasiland Sweden Schweden Switzerland Schweiz Syria Syrien Taiwan Taiwan Tajikistan Tadschikistan Tanzania Tansania Thailand Thailand Togo Togo Tokelau Tokelau Tonga Tonga TrinidadAndTobago Trinidad und Tobago Tunisia Tunesien Turkey Türkei Turkmenistan Turkmenistan TurksAndCaicosIslands Turks- und Caicosinseln Tuvalu Tuvalu Uganda Uganda Ukraine Ukraine UnitedArabEmirates Vereinigte Arabische Emirate UnitedKingdom Vereinigtes Königreich UnitedStates Vereinigte Staaten von Amerika Uruguay Uruguay Uzbekistan Usbekistan Vanuatu Vanuatu Venezuela Venezuela Vietnam Vietnam WallisAndFutunaIslands Wallis und Futuna Yemen Jemen Zambia Sambia Zimbabwe Simbabwe linphone-utils downloadCodecDescription Möchten Sie %1 (%2) herunterladen? linphone-desktop-4.2.5/linphone-app/assets/languages/en.ts000066400000000000000000002411411376717241300236370ustar00rootroot00000000000000 About ok OK ActivateAppSipAccountWithEmail activateAppSipAccount ACTIVATE YOUR %1 ACCOUNT confirmAction ACTIVATE activationSteps To activate your account: follow the instructions that we sent at %1, then click below. ActivateAppSipAccountWithPhoneNumber activateAppSipAccount ACTIVATE YOUR %1 ACCOUNT confirmAction ACTIVATE activationSteps An SMS containing a validation code was sent to %1. To complete the phone number verification, please enter the 4-digit code below. App commandLineOptionVerbose log to stdout some debug information while running commandLineOptionConfig specify the %1 configuration file to be used applicationDescription A free (libre) SIP video-phone. commandLineOptionIconified start in the system tray, do not show the main interface commandLineOptionConfigArg file commandLineOptionHelp show this help commandLineOptionVersion show app version commandLineOptionCliHelp displays the help menu to use %1 with the CLI commandLineDescription send an order to the application towards a command line restore Restore quit Quit settings Preferences about About AssistantAbstractView back BACK AssistantHome useAppSipAccount USE A %1 ACCOUNT useOtherSipAccount USE A SIP ACCOUNT fetchRemoteConfiguration FETCH REMOTE CONFIGURATION homeTitle WELCOME homeDescription This assistant will help you configure and use your sip account. createAppSipAccount CREATE A %1 ACCOUNT AssistantModel loginWithUsernameFailed Login failed. Please check your username/password. usernameStatusTooShort Too short! (%1 characters min.) usernameStatusTooLong Too long! (%1 characters max.) usernameStatusInvalidCharacters Invalid characters detected. (regex: `%1`) usernameStatusInvalid Invalid username. passwordStatusTooShort Too short! (%1 characters min.) passwordStatusTooLong Too long! (%1 characters max.) passwordStatusInvalidCharacters Invalid characters detected. (regex: `%1`) passwordStatusMissingCharacters Missing characters: `%1`. requestFailed Unable to send the request. emailStatusMalformed Incorrect email address. emailStatusMalformedInvalidCharacters Incorrect email address or invalid characters. cannotSendSms Server error: cannot send sms. accountAlreadyExists This account already exists. smsActivationFailed SMS activation failed! emailActivationFailed Please verify that you have validated your account or try again. phoneNumberStatusInvalid Invalid phone number! phoneNumberStatusTooShort Too short! phoneNumberStatusTooLong Too long! phoneNumberStatusInvalidCountryCode Invalid country code! loginWithPhoneNumberFailed Login failed. Please check your phone number. unableToAddAccount Unable to add this account. AuthenticationRequest cancel CANCEL confirm LOGIN identityLabel Identity passwordLabel Password authenticationRequestDescription Unable to authenticate. Please verify your password. userIdLabel User ID (optional) realmLabel Realm CallModel callStatsCodec Codec callStatsUploadBandwidth Upload bandwidth callStatsDownloadBandwidth Download bandwidth callStatsEstimatedDownloadBandwidth Estimated download bandwidth callStatsIceState ICE state callStatsIpFamily IP family callStatsSenderLossRate Sender loss rate callStatsReceiverLossRate Receiver loss rate callStatsJitterBuffer Jitter buffer callStatsSentVideoDefinition Sent video definition callStatsReceivedVideoDefinition Received video definition iceStateNotActivated Not activated iceStateFailed Failed iceStateInProgress In progress iceStateReflexiveConnection Reflexive connection iceStateHostConnection Host connection iceStateRelayConnection Relay connection iceStateInvalid Invalid callErrorDeclined Remote party declined the call. callErrorNotFound Remote party was not found. callErrorBusy Remote party is busy. callErrorNotAcceptable Remote party cannot accept the call. callStatsReceivedFramerate Received framerate callStatsSentFramerate Sent framerate CallSipAddress cancel CANCEL callSipAddressDescription Start a new call. CallStatistics audioStatsLabel Audio videoStatsLabel Video CallTransfer cancel CANCEL callTransferDescription Do you want to transfer this call? Calls acceptAudioCall ACCEPT AUDIO CALL acceptVideoCall ACCEPT VIDEO CALL terminateCall END CALL resumeCall RESUME CALL transferCall TRANSFER CALL callPause HOLD CALL CallsWindow callsTitle Calls acceptClosingDescription Are you sure you want to terminate all calls? Chat newMessagePlaceholder Enter your message noFileTransferUrl Unable to send file. Server URL not configured. isComposing %1 is typing... Cli appCliDescription Way to control the %1 application through command lines. uriCommandLineSyntax %1 <sip-address>?method=<method>([&<argument>=<base64-value>]*) cliCommandLineSyntax %1 "<method> ([<argument>=<value>]*)" commandsName commands list : showFunctionDescription Show the main window of the application. callFunctionDescription Initiate a call to the sip-address. initiateConferenceFunctionDescription Initiate a conference. joinConferenceFunctionDescription Join the conference hosted by the sip-address as display-name. If you are connected to a proxy config, see join-conference-as. joinConferenceAsFunctionDescription Join the conference hosted by the sip-address as with the guest-sip-address. If you are not connected to a proxy-config, see join-conference. CodecsViewer codecMime Name codecEncoderDescription Description codecEncoderClockRate Rate (Hz) codecBitrate Bitrate (Kbit/s) codecRecvFmtp Parameters codecStatus Status Conference conferenceTitle CONFERENCE ConferenceControls conference CONFERENCE ConferenceManager conferenceManagerDescription Manage participants to your conference. cancel CANCEL confirm START ConfirmDialog cancel CANCEL confirm CONFIRM ContactEdit removeContactDescription Do you really want to remove this contact from your address book? sipAccounts SIP ACCOUNT(S) address ADDRESS emails E-MAIL(S) webSites WEBSITE(S) avatarChooserTitle Choose your avatar companies COMPANIES save SAVE cancel CANCEL sipAccountsPlaceholder SIP account companiesPlaceholder Company emailsPlaceholder Email webSitesPlaceholder Website street Street postalCode Postal code country Country locality Locality abortEditDescriptionText Are you sure you want to cancel the contact modification? tooltipShowConversation Show conversation Contacts searchContactPlaceholder Search contact selectAllContacts All selectConnectedContacts Connected addContact ADD CONTACT removeContactDescription Do you really want to remove this contact from your address book? Conversation displayCallsAndMessages ALL displayCalls CALLS displayMessages MESSAGES removeAllEntriesDescription Are you sure you want to clear this history? tooltipContactEdit Edit contact tooltipContactAdd Add contact cleanHistory Delete history CreateAppSipAccount createAppSipAccountDescription How would you like to create your account? createAppSipAccountTitle CREATE A %1 ACCOUNT withPhoneNumber WITH A PHONE NUMBER withEmailAddress WITH AN EMAIL ADDRESS CreateAppSipAccountWithEmail createAppSipAccountTitle CREATE A %1 ACCOUNT confirmAction CREATE usernameLabel Username emailLabel Email passwordLabel Password passwordConfirmationLabel Password confirmation passwordConfirmationError The passwords you entered do not match. quitWarning Your account has been created but has not been validated yet. Are you sure you want to quit this view? displayNameLabel Display name (optional) CreateAppSipAccountWithPhoneNumber createAppSipAccountTitle CREATE A %1 ACCOUNT countryLabel Country phoneNumberLabel Phone number usernameLabel Username displayNameLabel Display name (optional) confirmAction CREATE quitWarning Your account has been created but has not been validated yet. If you quit this view, you would have to manually add and validate your account within 24 hours. DroppableTextArea fileChooserTitle Please choose one or more files dropYourAttachment Drop your attachment attachmentTooltip Send a file Event incomingCall Incoming call outgoingCall Outgoing call declinedIncomingCall Declined incoming call declinedOutgoingCall Declined outgoing call endedCall Terminated call missedIncomingCall Missed incoming call missedOutgoingCall Missed outgoing call FetchRemoteConfiguration confirmAction FETCH fetchRemoteConfigurationTitle FETCH REMOTE CONFIGURATION urlLabel URL remoteProvisioningError Unable to set this remote provisioning uri. remoteProvisioningUpdateDescription It is necessary to restart the application. Do you want to restart now? HistoryView removeAllEntriesDescription Are you sure you want to clear this history? tooltipContactEdit Edit contact tooltipContactAdd Add contact cleanHistory Delete history Home howToDescription Need help on how to use %1? howToTitle HOW TO USE %1 inviteDescription Invite your friends on %1. inviteTitle INVITE YOUR FRIENDS accountAssistantDescription Create or manage your %1 account. accountAssistantTitle ACCOUNT ASSISTANT assistantButton ASSISTANT showTooltips Show tooltips inviteButton INVITE Incall acceptVideoDescription Your contact would like to turn on video. pendingRequestLabel Please wait, a request is pending. securedStringFormat Call is encrypted with: %1. callNotSecured Call not encrypted. takeSnapshotLabel Take a snapshot. startRecordingLabel Start recording. stopRecordingLabel Stop recording. IncallFullscreenWindow takeSnapshotLabel Take a snapshot. startRecordingLabel Start recording. stopRecordingLabel Stop recording. InviteFriends enterEmailLabel Friend's email address messageLabel Message cancel CANCEL confirm CONFIRM inviteFriendsTitle Invite Friends defaultMessage %1 wants to invite you on %2! defaultSubject %1 invitation forcedMessage Download the application on your computer and start calling and chatting with users for free. Click here: <a href="%1">%1</a> MainWindow mainSearchBarPlaceholder Search contact, start a call or a chat... homeEntry HOME contactsEntry CONTACTS autoAnswerStatus auto smartSearchBarTooltip Use the intelligent search bar to directly start audio and video calls, send a message or add a new contact. Just enter your friend's SIP address or username. newConferenceButton Start conference call MainWindowMenuBar settings Preferences about About quit Quit MainWindowTopMenuBar settings Preferences about About quit Quit ManageAccounts ok OK selectPresenceLabel Presence status selectAccountLabel Active account Message menuCopy Copy menuPlayMe Play me! MultimediaParameters ok OK Notifier newVersionAvailable A new version (%1) is available! newFileMessage New attachment received! OnlineInstallerDialog confirm CONFIRM onlineInstallerExtractingDescription Extracting %1... onlineInstallerDownloadingDescription Downloading %1... onlineInstallerFinishedDescription %1 is now installed! onlineInstallerFailedDescription Failed to install %1! OutgoingMessage messageError Error messageRead Read messageDelivered Delivered Presence presenceOnline Available presenceBusy Busy presenceDoNotDisturb Do not disturb presenceOffline Offline SettingsAdvanced logsTitle Logs logsFolderLabel Logs folder sendLogs SEND LOGS logsUploadUrlLabel Logs upload server URL logsUploadFailed Failed to upload logs. logsEnabledLabel Enable logs cleanLogs CLEAN LOGS cleanLogsDescription Are you sure you want to remove all logs? developerSettingsTitle Developer settings developerSettingsEnabledLabel Enable developer settings logsMailerFailed Message when Linphone try to open a mailer to send logs, after uploading them to the server (%1 would be the upload url) Mailer cannot be found but logs were uploaded to %1 logsMailerSuccess Logs were uploaded to %1 SettingsAudio audioTitle Audio parameters playbackDeviceLabel Playback device captureDeviceLabel Capture device ringerDeviceLabel Ringer device ringLabel Ring echoCancellationLabel Enable echo cancellation audioCodecsTitle Audio codecs showAudioCodecsLabel Show audio codecs playbackGainLabel Playback gain captureGainLabel Capture gain audioTestLabel Capture level audioSettingsInCallWarning Audio call in progress: some settings are not available. SettingsCallsChat fileServerLabel File server encryptWithLimeLabel Encrypt with LIME limeDisabled Disabled limeRequired Mandatory limePreferred Preferred chatTitle Chat callsTitle Calls encryptionLabel Encryption noEncryption None autoAnswerLabel Auto answer autoAnswerDelayLabel Delay (in ms) autoAnswerWithVideoLabel Auto answer (with video) chatEnabledLabel Enable chat callRecorderEnabledLabel Enable call recorder chatNotificationSoundEnabledLabel Enable notification sound chatNotificationSoundLabel Notification sound conferenceEnabledLabel Enable conference contactsTitle Contacts contactsEnabledLabel Enable contacts muteMicrophoneEnabledLabel Enable mute microphone outgoingCallsEnabledLabel Enable outgoing calls showTelKeypadAutomaticallyLabel Show telephone keypad automatically automaticallyRecordCallsLabel Automatically record calls keepCallsWindowInBackgroundLabel Keep calls windows in background callPauseEnabledLabel Hold call enabled encryptionMandatoryLabel Encrytion is mandatory SettingsNetwork sendDtmfsLabel DTMFs sending method allowIpV6Label Allow IPv6 transportTitle Transport natAndFirewallTitle NAT and Firewall enableIceLabel Enable ICE stunServerLabel STUN/TURN server enableTurnLabel Enable TURN turnUserLabel TURN user turnPasswordLabel TURN password networkProtocolAndPortsTitle Network protocol and Ports sipUdpPortLabel Set SIP/UDP listening port sipTcpPortLabel Set SIP/TCP listening port audioRtpUdpPortLabel Audio RTP UDP port videoRtpUdpPortLabel Video RTP UDP port dscpFieldsTitle DSCP Fields sipFieldLabel SIP audioRtpStreamFieldLabel Audio RTP Stream videoRtpStreamFieldLabel Video RTP Stream bandwidthControlTitle Bandwidth Control downloadSpeedLimitLabel Download speed limit in Kbit/sec uploadSpeedLimitLabel Upload speed limit in Kbit/sec enableAdaptiveRateControlLabel Enable adaptive rate control presenceTitle Presence rlsUriLabel Use RLS URI rlsUriAuto AUTO rlsUriDisabled NEVER showNetworkSettingsLabel Show network settings generalTitle General SettingsSipAccounts defaultIdentityTitle Default identity defaultUsernameLabel Username defaultSipAddressLabel SIP address proxyAccountsTitle Proxy accounts eraseAllPasswords REMOVE ALL PASSWORDS addAccount ADD ACCOUNT editHeader Edit deleteHeader Delete deleteAccountDescription Are you sure you wish to delete this account? eraseAllPasswordsDescription Are you sure you wish to remove all passwords? defaultDisplayNameLabel Display name assistantTitle Assistant createAppSipAccountEnabledLabel Enable account creation useAppSipAccountEnabledLabel Enable account usage useOtherSipAccountEnabledLabel Enable generic account usage fetchRemoteConfigurationEnabledLabel Enable configuration fetch assistantSupportsPhoneNumbersLabel Supports phone numbers SettingsSipAccountsEdit sipAddressLabel SIP address transportLabel Transport serverAddressLabel SIP Server address registrationDurationLabel Registration duration (sec) routeLabel Route contactParamsLabel Contact params publishPresenceLabel Publish presence information avpfIntervalLabel AVPF regular RTCP interval (sec) registerEnabledLabel Register avpfEnabledLabel Enable AVPF cancel CANCEL confirm CONFIRM invalidSipAddress Invalid SIP address. invalidServerAddress Invalid server address. invalidRoute Invalid route. enableIceLabel Enable ICE stunServerLabel STUN/TURN server enableTurnLabel Enable TURN turnUserLabel TURN user turnPasswordLabel TURN password natAndFirewallTitle NAT and Firewall mainSipAccountSettingsTitle Main SIP account settings SettingsUi pathsTitle Paths savedScreenshotsLabel Saved screenshots folder savedCallsLabel Saved calls folder languagesTitle Languages languagesLabel Language systemLocale System locale cleanAvatars ERASE AVATARS cleanAvatarsDescription Are you sure you want to erase all avatars? downloadLabel Download folder setLocaleDescription It is necessary to restart the application. Do you want to restart now? otherTitle Other exitOnCloseLabel Exit app on close window dataTitle UI Data autoStartLabel Autostart app SettingsVideo videoInputDeviceLabel Video input device videoFramerateLabel Framerate videoCaptureTitle Video capture parameters videoPresetLabel Video preset presetDefault Default presetHighFps High FPS presetCustom Custom videoSizeLabel Video resolution videoCodecsTitle Video codecs showCameraPreview VIDEO PREVIEW showVideoCodecsLabel Show video codecs videoSettingsInCallWarning Video call in progress: some settings are not available. SettingsVideoPreview confirm OK SettingsWindow settingsTitle Settings sipAccountsTab SIP accounts audioTab Audio videoTab Video callsAndChatTab Calls and Chat networkTab Network uiTab User Interface validButton OK uiAdvanced Advanced SmartSearchBar addContact ADD CONTACT Timeline timelineTitle Previously UseAppSipAccount confirmAction USE useAppSipAccountTitle USE A %1 ACCOUNT useUsernameToLogin Use username and password rather than your phone number. quitWarning Your account has been created but has not been validated yet. Are you sure you want to quit this view? UseAppSipAccountWithPhoneNumber countryLabel Country phoneNumberLabel Phone number UseAppSipAccountWithUsername usernameLabel Username passwordLabel Password UseOtherSipAccount confirmAction USE useOtherSipAccountTitle USE A SIP ACCOUNT usernameLabel Username displayNameLabel Display name (optional) sipDomainLabel SIP Domain passwordLabel Password transportLabel Transport addOtherSipAccountError Unable to add this account. ZrtpTokenAuthentication confirmSas Confirm the following SAS with peer. codeA Say: codeB Your contact should say: deny DENY accept CONFIRM country Afghanistan Afghanistan Albania Albania Algeria Algeria AmericanSamoa American Samoa Andorra Andorra Angola Angola Anguilla Anguilla AntiguaAndBarbuda Antigua and Barbuda Argentina Argentina Armenia Armenia Aruba Aruba Australia Australia Austria Austria Azerbaijan Azerbaijan Bahamas Bahamas Bahrain Bahrain Bangladesh Bangladesh Barbados Barbados Belarus Belarus Belgium Belgium Belize Belize Benin Benin Bermuda Bermuda Bhutan Bhutan Bolivia Bolivia BosniaAndHerzegowina Bosnia and Herzegovina Botswana Botswana Brazil Brazil Brunei Brunei Bulgaria Bulgaria BurkinaFaso Burkina Faso Burundi Burundi Cambodia Cambodia Cameroon Cameroon Canada Canada CapeVerde Cape Verde CaymanIslands Cayman Islands CentralAfricanRepublic Central African Republic Chad Chad Chile Chile China China Colombia Colombia Comoros Comoros PeoplesRepublicOfCongo Republic of the Congo DemocraticRepublicOfCongo Democratic Republic of Congo CookIslands Cook Islands CostaRica Costa Rica IvoryCoast Ivory Coast Croatia Croatia Cuba Cuba Cyprus Cyprus CzechRepublic Czech Republic Denmark Denmark Djibouti Djibouti Dominica Dominica DominicanRepublic Dominican Republic Ecuador Ecuador Egypt Egypt ElSalvador El Salvador EquatorialGuinea Equatorial Guinea Eritrea Eritrea Estonia Estonia Ethiopia Ethiopia FalklandIslands Falkland Islands FaroeIslands Faroe Islands Fiji Fiji Finland Finland France France FrenchGuiana French Guiana FrenchPolynesia French Polynesia Gabon Gabon Gambia Gambia Georgia Georgia Germany Germany Ghana Ghana Gibraltar Gibraltar Greece Greece Greenland Greenland Grenada Grenada Guadeloupe Guadeloupe Guam Guam Guatemala Guatemala Guinea Guinea GuineaBissau Guinea Bissau Guyana Guyana Haiti Haiti Honduras Honduras HongKong Hong Kong Hungary Hungary Iceland Iceland India India Indonesia Indonesia Iran Iran Iraq Iraq Ireland Ireland Israel Israel Italy Italy Jamaica Jamaica Japan Japan Jordan Jordan Kazakhstan Kazakhstan Kenya Kenya Kiribati Kiribati DemocraticRepublicOfKorea Democratic Republic of Korea RepublicOfKorea Republic of Korea Kuwait Kuwait Kyrgyzstan Kyrgyzstan Laos Laos Latvia Latvia Lebanon Lebanon Lesotho Lesotho Liberia Liberia Libya Libya Liechtenstein Liechtenstein Lithuania Lithuania Luxembourg Luxembourg Macau Macau Macedonia Macedonia Madagascar Madagascar Malawi Malawi Malaysia Malaysia Maldives Maldives Mali Mali Malta Malta MarshallIslands Marshall Islands Martinique Martinique Mauritania Mauritania Mauritius Mauritius Mayotte Mayotte Mexico Mexico Micronesia Micronesia Moldova Moldova Monaco Monaco Mongolia Mongolia Montenegro Montenegro Montserrat Montserrat Morocco Morocco Mozambique Mozambique Myanmar Myanmar Namibia Namibia NauruCountry Nauru Nepal Nepal Netherlands Netherlands NewCaledonia New Caledonia NewZealand New Zealand Nicaragua Nicaragua Niger Niger Nigeria Nigeria Niue Niue NorfolkIsland Norfolk Island NorthernMarianaIslands Northern Mariana Islands Norway Norway Oman Oman Pakistan Pakistan Palau Palau PalestinianTerritories Palestinian Territories Panama Panama PapuaNewGuinea Papua New Guinea Paraguay Paraguay Peru Peru Philippines Philippines Poland Poland Portugal Portugal PuertoRico Puerto Rico Qatar Qatar Reunion Reunion Romania Romania RussianFederation Russian Federation Rwanda Rwanda SaintHelena Saint Helena SaintKittsAndNevis Saint Kitts And Nevis SaintLucia Saint Lucia SaintPierreAndMiquelon Saint Pierre And Miquelon SaintVincentAndTheGrenadines Saint Vincent And The Grenadines Samoa Samoa SanMarino San Marino SaoTomeAndPrincipe São Tomé And Principe SaudiArabia Saudi Arabia Senegal Senegal Serbia Serbia Seychelles Seychelles SierraLeone Sierra Leone Singapore Singapore Slovakia Slovakia Slovenia Slovenia SolomonIslands Solomon Islands Somalia Somalia SouthAfrica South Africa Spain Spain SriLanka Sri Lanka Sudan Sudan Suriname Suriname Swaziland Swaziland Sweden Sweden Switzerland Switzerland Syria Syria Taiwan Taiwan Tajikistan Tajikistan Tanzania Tanzania Thailand Thailand Togo Togo Tokelau Tokelau Tonga Tonga TrinidadAndTobago Trinidad And Tobago Tunisia Tunisia Turkey Turkey Turkmenistan Turkmenistan TurksAndCaicosIslands Turks And Caicos Islands Tuvalu Tuvalu Uganda Uganda Ukraine Ukraine UnitedArabEmirates United Arab Emirates UnitedKingdom United Kingdom UnitedStates United States Uruguay Uruguay Uzbekistan Uzbekistan Vanuatu Vanuatu Venezuela Venezuela Vietnam Vietnam WallisAndFutunaIslands Wallis And Futuna Islands Yemen Yemen Zambia Zambia Zimbabwe Zimbabwe linphone-utils downloadCodecDescription Do you want to download %1 (%2)? linphone-desktop-4.2.5/linphone-app/assets/languages/es.ts000066400000000000000000002444441376717241300236550ustar00rootroot00000000000000 About ok OK ActivateAppSipAccountWithEmail activateAppSipAccount Activa tu cuenta %1 confirmAction Activar activationSteps Para activar tu cuenta: sigue las instrucciones que enviaremos a %1, entonces de clic debajo. ActivateAppSipAccountWithPhoneNumber activateAppSipAccount Activa tu cuenta %1 confirmAction Activar activationSteps Le hemos enviado un SMS con el código de verificación a %1. Para completar la verificación de su número telefónico entre los 4 dígitos de abajo. App commandLineOptionVerbose Iniciar sesión para excluir cierta información de depuración mientras se ejecuta. commandLineOptionConfig Especificar el fichero de configuración de %1 para ser usado applicationDescription Un software libre de videollamadas SIP commandLineOptionIconified iniciar en la bandeja del sistema, no mostrar en la pantalla principal commandLineOptionConfigArg archivo commandLineOptionHelp mostrar esta ayuda commandLineOptionVersion mostrar versión del programa commandLineOptionCliHelp mostrar el menú de ayuda para usar %1 desde la línea de comandos commandLineDescription enviar una orden a la aplicación hacia la línea de comandos restore Restaurar quit Salir settings Preferencias about Acerca De AssistantAbstractView back ATRÁS AssistantHome useAppSipAccount USAR UNA CUENTA DE %1 useOtherSipAccount USAR UNA CUENTA SIP fetchRemoteConfiguration RECOGER CONFIGURACIÓN REMOTA homeTitle BIENVENIDO homeDescription Este asistente le ayudará a configurar y usar su cuenta %1. createAppSipAccount CREAR UNA CUENTA %1 AssistantModel loginWithUsernameFailed Autenticación fallida. Por favor chequee su usuario y contraseña. usernameStatusTooShort Muy corta (%1 caracteres mínimo) usernameStatusTooLong Muy larga (%1 caracteres máximo) usernameStatusInvalidCharacters Se han detectado caracteres inválidos. (regex: `%1`) usernameStatusInvalid Usuario incorrecto. passwordStatusTooShort Muy corta (%1 caracteres mínimo) passwordStatusTooLong Muy larga (%1 caracteres máximo) passwordStatusInvalidCharacters Se han detectado caracteres inválidos. (regex: `%1`) passwordStatusMissingCharacters Caracteres faltantes: `%1`. requestFailed No se puede enviar la petición. emailStatusMalformed Dirección de correo incorrecta. emailStatusMalformedInvalidCharacters Email incorrecto o carácteres inválidos. cannotSendSms Error del servidor: no se pudo enviar el sms. accountAlreadyExists Esta cuenta ya existe. smsActivationFailed ¡Activación SMS fallida! emailActivationFailed Por favor, verifique que ha validado su cuenta e inténtelo de nuevo. phoneNumberStatusInvalid Número telefónico inválido! phoneNumberStatusTooShort Muy corto! phoneNumberStatusTooLong Muy largo! phoneNumberStatusInvalidCountryCode ¡Código de país inválido! loginWithPhoneNumberFailed Inicio de sesión fallido. Compruebe su número de teléfono. unableToAddAccount Imposible añadir esta cuenta. AuthenticationRequest cancel CANCELAR confirm INICIAR SESIÓN identityLabel Identidad passwordLabel Contraseña authenticationRequestDescription Imposible autentificar. Por favor, verifique su contraseña. userIdLabel ID de usuario (opcional) realmLabel Realm CallModel callStatsCodec Códec callStatsUploadBandwidth Ancho de banda de subida callStatsDownloadBandwidth Ancho de banda de bajada callStatsEstimatedDownloadBandwidth Ancho de banda estimado callStatsIceState Estado ICE callStatsIpFamily Familia de IP callStatsSenderLossRate Tasa de pérdida del emisor callStatsReceiverLossRate Tasa de pérdida del receptor callStatsJitterBuffer Buffer jitter callStatsSentVideoDefinition Definición de video enviada callStatsReceivedVideoDefinition Definición de video recivida iceStateNotActivated No activado iceStateFailed Fallido iceStateInProgress En progreso iceStateReflexiveConnection Conexión reflexiva iceStateHostConnection Conexión de host iceStateRelayConnection Conexión de relé iceStateInvalid Inválido callErrorDeclined La parte remota rechazó la llamada. callErrorNotFound No se encontró la parte remota. callErrorBusy La fiesta remota está ocupada. callErrorNotAcceptable La parte remota no puede aceptar la llamada. callStatsReceivedFramerate Tasa de frames recividos callStatsSentFramerate Tasa de frames enviados CallSipAddress cancel CANCELAR callSipAddressDescription Empezar nueva llamada. CallStatistics audioStatsLabel Audio videoStatsLabel Video CallTransfer cancel CANCELAR callTransferDescription ¿Desea transferir esta llamada? Calls acceptAudioCall ACEPTAR LLAMADA DE AUDIO acceptVideoCall ACEPTAR VIDEOLLAMADA terminateCall COLGAR resumeCall RESUMIR LLAMADA transferCall TRANSFERIR LLAMADA callPause PAUSAR LLAMADA CallsWindow callsTitle Llamadas acceptClosingDescription ¿Está seguro de que desea terminar todas las llamadas? Chat newMessagePlaceholder Introduzca su mensaje noFileTransferUrl Imposible enviar fichero. URL del servidor no configurada. isComposing %1 está escribiendo... Cli appCliDescription Manera de controlar la aplicación %1 a través de líneas de comando. uriCommandLineSyntax %1 <sip-address>?method=<method>([&<argument>=<base64-value>] *) cliCommandLineSyntax %1 "<method> ([<argument> = <value>] *)» commandsName lista de comandos: showFunctionDescription Mostrar la pantalla principal de la aplicación callFunctionDescription Inicializar una llamada a la dirección sip initiateConferenceFunctionDescription Inicia una conferencia joinConferenceFunctionDescription Únase a la conferencia organizada por la dirección sip-name como display-name. Si está conectado a una configuración de proxy, consulte join-conference-as. joinConferenceAsFunctionDescription Únase a la conferencia organizada por la dirección de sip-como con la dirección de sip-guest. Si no está conectado a un proxy-config, consulte join-conference. CodecsViewer codecMime Nombre codecEncoderDescription Descripcion codecEncoderClockRate Tasa (Hz) codecBitrate Tasa de bits (Kbit/s) codecRecvFmtp Parámetros codecStatus Estatus Conference conferenceTitle CONFERENCIA ConferenceControls conference CONFERENCIA ConferenceManager conferenceManagerDescription Administrar participantes para tu conferencia cancel CANCELAR confirm INICIAR ConfirmDialog cancel CANCELAR confirm CONFIRMAR ContactEdit removeContactDescription ¿Desea realmente eliminar este contacto de su lista de contactos? sipAccounts CUENTA(S) SIP address DIRECCIÓN emails E-MAILS(S) webSites SITIO(S) WEB avatarChooserTitle Elija su avatar companies COMPAÑÍAS save GUARDAR cancel CANCELAR sipAccountsPlaceholder Cuenta SIP companiesPlaceholder Empresa emailsPlaceholder Email webSitesPlaceholder Sitio web street Calle postalCode Código postal country País locality Localidad abortEditDescriptionText ¿Estás seguro de que quieres cancelar las modificaciones del contacto? tooltipShowConversation Mostrar conversación Contacts searchContactPlaceholder Buscar contacto selectAllContacts Todo selectConnectedContacts Conectado addContact AÑADIR CONTACTO removeContactDescription ¿Realmente quieres eliminar este contacto de tu lista de contactos? Conversation displayCallsAndMessages TODO displayCalls LLAMADAS displayMessages MENSAJES removeAllEntriesDescription ¿Estás seguro de que quieres limpiar este historial? tooltipContactEdit Editar contacto tooltipContactAdd Añadir contacto cleanHistory Eliminar historial CreateAppSipAccount createAppSipAccountDescription ¿Cómo prefieres crear tu cuenta? createAppSipAccountTitle CREAR UNA CUENTA %1 withPhoneNumber CON UN NÚMERO DE TELÉFONO withEmailAddress CON UN CORREO ELECTRÓNICO CreateAppSipAccountWithEmail createAppSipAccountTitle CREAR UNA CUENTA %1 confirmAction CREAR usernameLabel Usuario emailLabel Email passwordLabel Contraseña passwordConfirmationLabel Confirmación de contraseña passwordConfirmationError Las contraseñas que has introducido no coinciden. quitWarning Su cuenta ha sido creada pero no ha sido validada aún. ¿Estás seguro de que deseas cerrar esta pantalla? displayNameLabel Nombre mostrado (opcional) CreateAppSipAccountWithPhoneNumber createAppSipAccountTitle CREAR UNA CUENTA %1 countryLabel País phoneNumberLabel Número de teléfono usernameLabel Usuario displayNameLabel Nombre mostrado (opcional) confirmAction CREAR quitWarning Tu cuenta se ha creado pero aún no se ha validado. Si sales de esta vista, tendrás que agregar y validar manualmente tu cuenta en un plazo de 24 horas. DroppableTextArea fileChooserTitle Por favor elija uno o más archivos dropYourAttachment Arrastre su adjunto attachmentTooltip Enviar un archivo Event incomingCall Llamada entrante outgoingCall Llamada saliente declinedIncomingCall Llamada entrante rechazada declinedOutgoingCall Llamada saliente rechazada endedCall Llamada terminada missedIncomingCall Llamada entrante perdida missedOutgoingCall Llamada saliente perdida FetchRemoteConfiguration confirmAction OBTENER fetchRemoteConfigurationTitle OBTENER CONFIGURACIÓN REMOTA urlLabel URL remoteProvisioningError Imposible establecer la uri de aprovisionamiento remota. remoteProvisioningUpdateDescription Es necesario reiniciar la aplicación. ¿Desea reiniciarla ahora? HistoryView removeAllEntriesDescription ¿Estás seguro de que quieres limpiar este historial? tooltipContactEdit Editar contacto tooltipContactAdd Añadir contacto cleanHistory Eliminar historial Home howToDescription ¿Necesitas ayuda sobre cómo utilizar %1? howToTitle COMO UTILIZAR %1 inviteDescription Invitar a sus amigos a %1. inviteTitle INVITA A TUS AMIGOS accountAssistantDescription Crear o administrar su cuenta %1 accountAssistantTitle ASISTENTE DE CUENTA assistantButton ASISTENTE showTooltips Mostrar tooltips inviteButton INVITAR Incall acceptVideoDescription Su contacto desea que habilite el vídeo. pendingRequestLabel Por favor espere, una petición está pendiente. securedStringFormat La llamada está cifrada con: %1. callNotSecured Llamada no cifrada. takeSnapshotLabel Tomar una captura. startRecordingLabel Empezar grabación. stopRecordingLabel Parar grabación. IncallFullscreenWindow takeSnapshotLabel Tomar una captura. startRecordingLabel Empezar grabación. stopRecordingLabel Parar grabación. InviteFriends enterEmailLabel Emails de sus amigos messageLabel Mensaje cancel CANCELAR confirm CONFIRMAR inviteFriendsTitle Invitar Amigos defaultMessage ¡%1 te quiere invitar a %2! defaultSubject Invitación de %1 forcedMessage Descargue la aplicación en su computadora y comience a llamar y chatear con los usuarios de forma gratuita. Haga clic aquí: <a href="%1">%1 </a> MainWindow mainSearchBarPlaceholder Buscar contacto, empezar una llamada o un chat homeEntry INICIO contactsEntry CONTACTOS autoAnswerStatus automático smartSearchBarTooltip Utilice la barra de búsqueda inteligente para iniciar directamente audio y vídeo , enviar un mensaje o agregar un nuevo contacto. Sólo tienes que entrar la dirección SIP o el nombre de usuario de su amigo. newConferenceButton Iniciar llamada de conferencia MainWindowMenuBar settings Preferencias about Sobre nosotros quit Cerrar MainWindowTopMenuBar settings Preferencias about Sobre quit Renunciar ManageAccounts ok OK selectPresenceLabel Estado de presencia selectAccountLabel Cuenta activa Message menuCopy Copiar menuPlayMe ¡Reprodúceme! MultimediaParameters ok OK Notifier newVersionAvailable ¡Una nueva versión (%1) está disponible! newFileMessage ¡Nuevo adjunto recivido! OnlineInstallerDialog confirm CONFIRMAR onlineInstallerExtractingDescription Extrayendo %1... onlineInstallerDownloadingDescription Descargando %1... onlineInstallerFinishedDescription ¡%1 está ahora instalado! onlineInstallerFailedDescription ¡Error al instalar %1! OutgoingMessage messageError Error messageRead Leído messageDelivered Enviado Presence presenceOnline Disponible presenceBusy Ocupado presenceDoNotDisturb No molestar presenceOffline Desconectado SettingsAdvanced logsTitle Registros logsFolderLabel Carpeta de registros sendLogs ENVIAR REGISTROS logsUploadUrlLabel URL del servidor de carga de registros logsUploadFailed Fallo al subir logs. logsEnabledLabel Activar logs cleanLogs LIMPIAR LOGS cleanLogsDescription ¿Estás seguro de que deseas eliminar todos los registros? developerSettingsTitle Ajustes de desarrollador developerSettingsEnabledLabel Activar ajustes de desarrollador logsMailerFailed Message when Linphone try to open a mailer to send logs, after uploading them to the server (%1 would be the upload url) No se puede encontrar el correo, pero los registros se cargaron a %1 logsMailerSuccess Los registros se cargaron a %1 SettingsAudio audioTitle Parámetros de audio playbackDeviceLabel Dispositivo de reproducción captureDeviceLabel Dispositivo de entrada ringerDeviceLabel Dispositivo de llamada ringLabel Tono de llamada echoCancellationLabel Activar la cancelación de echo audioCodecsTitle Códecs de audio showAudioCodecsLabel Mostrar códecs de audio playbackGainLabel Ganancia de reproducción captureGainLabel Captura de ganancia audioTestLabel Nivel de captura audioSettingsInCallWarning Llamada de audio en curso: algunos ajustes no están disponibles. SettingsCallsChat fileServerLabel Servidor de archivos encryptWithLimeLabel Encriptar con LIME limeDisabled Desactivado limeRequired Obligatorio limePreferred Preferido chatTitle Chat callsTitle Llamadas encryptionLabel Cifrado noEncryption Ninguno autoAnswerLabel Auto responder autoAnswerDelayLabel Retardo (en ms) autoAnswerWithVideoLabel Auto responder (con vídeo) chatEnabledLabel Activar chat callRecorderEnabledLabel Activar grabación de llamadas chatNotificationSoundEnabledLabel Activar sonido de notificación chatNotificationSoundLabel Sonido de notificación conferenceEnabledLabel Activar conferencia contactsTitle Contactos contactsEnabledLabel Activar contactos muteMicrophoneEnabledLabel Activar silencio micrófono outgoingCallsEnabledLabel Activar llamadas salientes showTelKeypadAutomaticallyLabel Mostar teclado de marcado automáticamente automaticallyRecordCallsLabel Grabar llamadas automáticamente keepCallsWindowInBackgroundLabel Mantener pantalla de llamadas en segundo plano callPauseEnabledLabel Llamada en espera activada encryptionMandatoryLabel El cifrado es obligatorio SettingsNetwork sendDtmfsLabel Método de envío DTMFs allowIpV6Label Permitir IPv6 transportTitle Transporte natAndFirewallTitle NAT y cortafuegos enableIceLabel Activar ICE stunServerLabel Servidor STUN/TURN enableTurnLabel Activar TURN turnUserLabel Usuario TURN turnPasswordLabel Contraseña TURN networkProtocolAndPortsTitle Protocolo de red y Puertos sipUdpPortLabel Puerto SIP UDP sipTcpPortLabel Puerto SIP TCP audioRtpUdpPortLabel Puerto audio RTP UDP videoRtpUdpPortLabel Puerto vídeo RTP UDP dscpFieldsTitle Campos DSCP sipFieldLabel SIP audioRtpStreamFieldLabel Stream de audio RTP videoRtpStreamFieldLabel Stream de vídeo RTP bandwidthControlTitle Control de ancho de banda downloadSpeedLimitLabel Velocidad límite de descarga en Kbit/seg uploadSpeedLimitLabel Velocidad límite de subida en Kbit/seg enableAdaptiveRateControlLabel Habilitar tasa de control adaptiva presenceTitle Presencia rlsUriLabel Usar URI RLS rlsUriAuto AUTOMÁTICO rlsUriDisabled NUNCA showNetworkSettingsLabel Mostrar ajustes de red generalTitle General SettingsSipAccounts defaultIdentityTitle Identidad por defecto defaultUsernameLabel Usuario defaultSipAddressLabel Dirección SIP proxyAccountsTitle Cuentas proxy eraseAllPasswords BORRAR CONTRASEÑAS addAccount AÑADIR CUENTA editHeader Editar deleteHeader Eliminar deleteAccountDescription ¿Estás seguro de que deseas eliminar esta cuenta? eraseAllPasswordsDescription ¿Estás seguro de que deseas eliminar todas las contraseñas? defaultDisplayNameLabel Nombre mostrado assistantTitle Asistente createAppSipAccountEnabledLabel Habilitar creación automática useAppSipAccountEnabledLabel Activar uso de cuenta useOtherSipAccountEnabledLabel Activar uso de cuenta automático fetchRemoteConfigurationEnabledLabel Habilitar obtención de configuración assistantSupportsPhoneNumbersLabel Soportar números de teléfono SettingsSipAccountsEdit sipAddressLabel Dirección SIP transportLabel Transporte serverAddressLabel Dirección del servidor SIP registrationDurationLabel Duración del registro (seg) routeLabel Ruta contactParamsLabel Parámetros de contacto publishPresenceLabel Publicar información de presencia avpfIntervalLabel Intervalo RTCP regular de AVPF (seg.) registerEnabledLabel Registrar avpfEnabledLabel Habilitar AVPF cancel CANCELAR confirm CONFIRMAR invalidSipAddress Dirección SIP inválida. invalidServerAddress Dirección del servidor inválida. invalidRoute Ruta inválida. enableIceLabel Activar ICE stunServerLabel Servidor STUN/TURN enableTurnLabel Activar TURN turnUserLabel Usuario TURN turnPasswordLabel Contraseña TURN natAndFirewallTitle NAT y cortafuegos mainSipAccountSettingsTitle Ajustes principales de cuenta SIP SettingsUi pathsTitle Rutas savedScreenshotsLabel Carpeta de capturas de pantalla savedCallsLabel Carpeta para llamadas guardadas languagesTitle Idiomas languagesLabel Idioma systemLocale Configuración regional del sistema cleanAvatars ELIMINAR AVATARES cleanAvatarsDescription ¿Estás seguro de que deseas eliminar todos los avatares? downloadLabel Carpeta de descargas setLocaleDescription Es necesario reiniciar la aplicación. ¿Deseas reiniciarla ahora? otherTitle Otro exitOnCloseLabel Salir de la aplicación al cerrar la ventana dataTitle Datos de la interfaz autoStartLabel Auto-iniciar aplicación SettingsVideo videoInputDeviceLabel Dispositivo de entrada de video videoFramerateLabel Tasa de frames videoCaptureTitle Parámetros de captura de video videoPresetLabel Preajuste de vídeo presetDefault Por defecto presetHighFps FPS alto presetCustom Personalizado videoSizeLabel Resolución de vídeo videoCodecsTitle Códecs de vídeo showCameraPreview PREVISUALIZACIÓN DE VIDEO showVideoCodecsLabel Mostrar códecs de vídeo videoSettingsInCallWarning Videollamada en curso: algunos ajustes no están disponibles. SettingsVideoPreview confirm OK SettingsWindow settingsTitle Ajustes sipAccountsTab Cuentas SIP audioTab Audio videoTab Vídeo callsAndChatTab Llamadas y Chat networkTab Red uiTab Interfaz de Usuario validButton OK uiAdvanced Avanzado SmartSearchBar addContact AÑADIR CONTACTO Timeline timelineTitle Previamente UseAppSipAccount confirmAction USO useAppSipAccountTitle USA UNA CUENTA %1 useUsernameToLogin Utilice nombre de usuario y contraseña en lugar de su número de teléfono. quitWarning Tu cuenta se ha creado pero aún no se ha validado. ¿Está seguro de que desea salir de esta vista? UseAppSipAccountWithPhoneNumber countryLabel País phoneNumberLabel Número de teléfono UseAppSipAccountWithUsername usernameLabel Usuario passwordLabel Contraseña UseOtherSipAccount confirmAction USE useOtherSipAccountTitle UTILIZE UNA CUENTA SIP usernameLabel Usuario displayNameLabel Nombre mostrado (opcional) sipDomainLabel Dominio SIP passwordLabel Contraseña transportLabel Transporte addOtherSipAccountError Imposible añadir esta cuenta. ZrtpTokenAuthentication confirmSas Confirma la siguiente SAS con el compañero codeA Dice: codeB Su contacto debería decir: deny DENEGAR accept CONFIRMAR country Afghanistan Afganistán Albania Albania Algeria Argelia AmericanSamoa Samoa Americana Andorra Andorra Angola Angola Anguilla Anguila AntiguaAndBarbuda Antigua y Barbuda Argentina Argentina Armenia Armenia Aruba Aruba Australia Australia Austria Austria Azerbaijan Azerbaiyán Bahamas Bahamas Bahrain Baréin Bangladesh Bangladés Barbados Barbados Belarus Belarús Belgium Bélgica Belize Bélice Benin Benín Bermuda Bermudas Bhutan Bután Bolivia Bolivia BosniaAndHerzegowina Bosnia y Herzegovina Botswana Botsuana Brazil Brasil Brunei Brunéi Bulgaria Bulgaria BurkinaFaso Burkina Faso Burundi Burundi Cambodia Camboya Cameroon Camerún Canada Canadá CapeVerde Cabo Verde CaymanIslands Islas Caimán CentralAfricanRepublic República Centroafricana Chad Chad Chile Chile China China Colombia Colombia Comoros Comoras PeoplesRepublicOfCongo República del Congo DemocraticRepublicOfCongo República Democrática del Congo CookIslands Islas Cook CostaRica Costa Rica IvoryCoast Costa de Marfil Croatia Croacia Cuba Cuba Cyprus Chipre CzechRepublic República Checa Denmark Dinamarca Djibouti Yibuti Dominica Dominica DominicanRepublic República Dominicana Ecuador Ecuador Egypt Egipto ElSalvador El Salvador EquatorialGuinea Guinea Ecuatorial Eritrea Eritrea Estonia Estonia Ethiopia Etiopía FalklandIslands Islas Malvinas (Falkland) FaroeIslands Islas Feroe Fiji Fiyi Finland Finlandia France Francia FrenchGuiana Guayana Francesa FrenchPolynesia Polinesia Francesa Gabon Gabón Gambia Gambia Georgia Georgia Germany Alemania Ghana Ghana Gibraltar Gibraltar Greece Grecia Greenland Groenlandia Grenada Granada Guadeloupe Guadalupe Guam Guam Guatemala Guatemala Guinea Guinea GuineaBissau Guinea Bissau Guyana Guyana Haiti Haití Honduras Honduras HongKong Hong Kong Hungary Hungría Iceland Islandia India India Indonesia Indonesia Iran Irán Iraq Irak Ireland Irlanda Israel Israel Italy Italia Jamaica Jamaica Japan Japón Jordan Jordania Kazakhstan Kazajstán Kenya Kenia Kiribati Kiribati DemocraticRepublicOfKorea República Democrática de Corea RepublicOfKorea República de Corea Kuwait Kuwait Kyrgyzstan Kirguistán Laos Laos Latvia Letonia Lebanon Líbano Lesotho Lesoto Liberia Liberia Libya Libia Liechtenstein Liechtenstein Lithuania Lituania Luxembourg Luxemburgo Macau Macau Macedonia Macedonia Madagascar Madagascar Malawi Malaui Malaysia Malasia Maldives Maldivas Mali Malí Malta Malta MarshallIslands Islas Marshall Martinique Martinica Mauritania Mauritania Mauritius Mauricio Mayotte Mayotte Mexico México Micronesia Micronesia Moldova Moldavia Monaco Mónaco Mongolia Mongolia Montenegro Montenegro Montserrat Montserrat Morocco Marruecos Mozambique Mozambique Myanmar Myanmar Namibia Namibia NauruCountry Nauru Nepal Nepal Netherlands Holanda NewCaledonia Nueva Caledonia NewZealand Nueva Zelanda Nicaragua Nicaragua Niger Níger Nigeria Nigeria Niue Niue NorfolkIsland Isla Norfolk NorthernMarianaIslands Islas Marianas del Norte Norway Noruega Oman Omán Pakistan Pakistán Palau Palaos PalestinianTerritories Territorios Palestinos Panama Panamá PapuaNewGuinea Papua Nueva Guinea Paraguay Paraguay Peru Perú Philippines Filipinas Poland Polonia Portugal Portugal PuertoRico Puerto Rico Qatar Catar Reunion Reunión Romania Rumania RussianFederation Federación de Rusia Rwanda Ruanda SaintHelena Santa Elena SaintKittsAndNevis San Cristóbal y Nieves SaintLucia Santa Lucía SaintPierreAndMiquelon San Pedro y Miquelón SaintVincentAndTheGrenadines San Vicente y las Granadinas Samoa Samoa SanMarino San Marino SaoTomeAndPrincipe Santo Tomé y Príncipe SaudiArabia Arabia Saudita Senegal Senegal Serbia Serbia Seychelles Seychelles SierraLeone Sierra Leona Singapore Singapur Slovakia Eslovaquia Slovenia Eslovenia SolomonIslands Islas Salomón Somalia Somalia SouthAfrica República de Corea Spain España SriLanka Sri Lanka Sudan Sudán Suriname Surinam Swaziland Suazilandia Sweden Suecia Switzerland Suiza Syria Siria Taiwan Taiwán Tajikistan Tayikistán Tanzania Tanzania Thailand Tailandia Togo Togo Tokelau Tokelau Tonga Tonga TrinidadAndTobago Trinidad y Tobago Tunisia Túnez Turkey Turquía Turkmenistan Turkmenistán TurksAndCaicosIslands Islas Turcas y Caicos Tuvalu Tuvalu Uganda Uganda Ukraine Ucrania UnitedArabEmirates Emiratos Árabes Unidos UnitedKingdom Reino Unido, Reino Unido UnitedStates Estados Unidos de América Uruguay Uruguay Uzbekistan Uzbekistán Vanuatu Vanuatu Venezuela Venezuela Vietnam Vietnam WallisAndFutunaIslands Islas Wallis y Futuna Yemen Yemen Zambia Zambia Zimbabwe Zimbabue linphone-utils downloadCodecDescription ¿Deseas descargar %1 (%1)? linphone-desktop-4.2.5/linphone-app/assets/languages/fr_FR.ts000066400000000000000000002454041376717241300242410ustar00rootroot00000000000000 About ok OK ActivateAppSipAccountWithEmail activateAppSipAccount ACTIVER VOTRE COMPTE %1 confirmAction ACTIVER activationSteps Pour activer votre compte : suivez les instructions que vous avez reçues à %1, puis cliquez sur le bouton ci-dessous. ActivateAppSipAccountWithPhoneNumber activateAppSipAccount ACTIVER VOTRE COMPTE %1 confirmAction ACTIVER activationSteps Un SMS de validation a été envoyé au %1. Afin de compléter la vérification du numéro de téléphone, veuillez entrer le code à 4 chiffres ci-dessous. App commandLineOptionVerbose afficher sur stdout les informations de debug commandLineOptionConfig spécifier un fichier de configuration à utiliser applicationDescription Un logiciel libre de voix sur IP SIP. commandLineOptionIconified lancer l'application dans la zone de notification commandLineOptionConfigArg file commandLineOptionHelp affiche cette aide commandLineOptionVersion affiche la version de l'application commandLineOptionCliHelp affiche le menu d'aide pour l'utilisation de %1 en CLI commandLineDescription envoie un ordre à l'application %1, voir --cli-help pour plus de détails restore Restaurer quit Quitter settings Préférences about À propos AssistantAbstractView back RETOUR AssistantHome useAppSipAccount UTILISER UN COMPTE %1 useOtherSipAccount UTILISER UN COMPTE SIP fetchRemoteConfiguration TÉLÉCHARGER UNE CONFIGURATION homeTitle BIENVENUE homeDescription Cet assistant va vous aider à configurer et utiliser votre compte SIP. createAppSipAccount CRÉER UN COMPTE %1 AssistantModel loginWithUsernameFailed La connection a échoué. Merci de vérifier le nom d'utilisateur/mot de passe. usernameStatusTooShort Trop court ! (%1 caractères min.) usernameStatusTooLong Trop long ! (%1 caractères max.) usernameStatusInvalidCharacters Caractères invalides détectés. (regex: `%1`) usernameStatusInvalid Nom d'utilisateur invalide. passwordStatusTooShort Trop court ! (%1 caractères min.) passwordStatusTooLong Trop long ! (%1 caractères max.)> passwordStatusInvalidCharacters Caractères invalides détectés. (regex: `%1`) passwordStatusMissingCharacters Caractères manquants : `%1`. requestFailed Impossible d'envoyer la requête. emailStatusMalformed Adresse incorrecte. emailStatusMalformedInvalidCharacters Adresse incorrecte ou caractères invalides. cannotSendSms Erreur serveur : impossible d'envoyer un sms. accountAlreadyExists Le compte existe déjà. smsActivationFailed L'activation par SMS a échoué ! emailActivationFailed Merci de vérifier que vous avez validé votre compte ou réessayez plus tard. phoneNumberStatusInvalid Numéro de tél. invalide ! phoneNumberStatusTooShort Trop court ! phoneNumberStatusTooLong Trop long ! phoneNumberStatusInvalidCountryCode Indicatif tél. invalide ! loginWithPhoneNumberFailed La connection a échoué. Merci de vérifier votre numéro. unableToAddAccount Impossible d'ajouter ce compte. AuthenticationRequest cancel ANNULER confirm SE CONNECTER identityLabel Identité passwordLabel Mot de passe authenticationRequestDescription Impossible de vous authentifier. Merci de vérifier votre mot de passe. userIdLabel ID utilisateur (optionnel) realmLabel Realm CallModel callStatsCodec Codec callStatsUploadBandwidth Bande passante d'envoi callStatsDownloadBandwidth Bande passante de réception callStatsEstimatedDownloadBandwidth Bande passante de réception estimée callStatsIceState État ICE callStatsIpFamily Famille IP callStatsSenderLossRate Taux de perte en envoi callStatsReceiverLossRate Taux de perte en réception callStatsJitterBuffer Tampon de gigue callStatsSentVideoDefinition Définition vidéo envoyée callStatsReceivedVideoDefinition Définition vidéo reçue iceStateNotActivated Désactivé iceStateFailed Échoué iceStateInProgress En cours iceStateReflexiveConnection Connexion réflexive iceStateHostConnection Connexion hôte iceStateRelayConnection Connexion relais iceStateInvalid Invalide callErrorDeclined Le correspondant a décliné l'appel. callErrorNotFound Le correspondant n'a pas été trouvé. callErrorBusy Le correspondant est occupé. callErrorNotAcceptable Le correspondant ne peut accepter votre appel. callStatsReceivedFramerate FPS reçues callStatsSentFramerate FPS envoyées CallSipAddress cancel ANNULER callSipAddressDescription Lancer un nouvel appel. CallStatistics audioStatsLabel Audio videoStatsLabel Vidéo CallTransfer cancel ANNULER callTransferDescription Voulez-vous transférer cet appel ? Calls acceptAudioCall ACCEPTER APPEL AUDIO acceptVideoCall ACCEPTER APPEL VIDEO terminateCall RACCROCHER resumeCall REPRENDRE L'APPEL transferCall TRANSFERER L'APPEL callPause PAUSE CallsWindow callsTitle Appels acceptClosingDescription Voulez-vous vraiment quitter tous vos appels en cours ? Chat newMessagePlaceholder Entrer votre message. noFileTransferUrl Impossible d'envoyer un fichier. Url du serveur non configurée. isComposing %1 est en train d'écrire... Cli appCliDescription Moyen d'effectuer des actions sur l'application %1 en ligne de commande. uriCommandLineSyntax %1 <sip-address>?method=<method>([&<argument>=<valeur-en-base64>]*) cliCommandLineSyntax %1 "<method> ([<argument>=<valeur>]*)" commandsName liste des commandes : showFunctionDescription Affiche la fenêtre principale de l'application. callFunctionDescription Initie un appel vers la sip-address. initiateConferenceFunctionDescription Initie une conférence. joinConferenceFunctionDescription Rejoint la conférence hébergée par la sip-address avec un display-name. Si vous êtes connecté à une proxy config, voir join-conference-as. joinConferenceAsFunctionDescription Rejoint la conférence hébergée par la sip-address avec la guest-sip-address. Si vous n'êtes pas connecté à une proxy-config, voir join-conference. CodecsViewer codecMime Nom codecEncoderDescription Description codecEncoderClockRate Fréquence (Hz) codecBitrate Débit (Kbit/s) codecRecvFmtp Paramètres codecStatus Status Conference conferenceTitle CONFÉRENCE ConferenceControls conference CONFÉRENCE ConferenceManager conferenceManagerDescription Gérer les participants de votre conférence. cancel ANNULER confirm LANCER ConfirmDialog cancel ANNULER confirm CONFIRMER ContactEdit removeContactDescription Voulez-vous vraiment supprimer ce contact de votre carnet ? sipAccounts COMPTE(S) SIP address ADRESSE emails EMAIL(S) webSites SITE(S) WEB avatarChooserTitle Choisissez votre avatar companies ENTREPRISE(S) save SAUVEGARDER cancel ANNULER sipAccountsPlaceholder Compte SIP companiesPlaceholder Entreprise emailsPlaceholder Email webSitesPlaceholder Site internet street Rue postalCode Code postal country Pays locality Localité abortEditDescriptionText Êtes-vous sûr de vouloir annuler l'édition du contact ? tooltipShowConversation Allez à la conversation Contacts searchContactPlaceholder Rechercher un contact selectAllContacts Tous selectConnectedContacts Connectés addContact AJOUTER UN CONTACT removeContactDescription Voulez-vous vraiment supprimer ce contact de votre carnet ? Conversation displayCallsAndMessages TOUT displayCalls APPELS displayMessages MESSAGES removeAllEntriesDescription Êtes-vous sûr de vouloir supprimer cet historique ? tooltipContactEdit Editer le contact tooltipContactAdd Ajouter le contact cleanHistory Supprimer l'historique CreateAppSipAccount createAppSipAccountDescription Comment souhaitez-vous créer votre compte ? createAppSipAccountTitle CRÉER UN COMPTE %1 withPhoneNumber AVEC UN NUMÉRO DE TÉLÉPHONE withEmailAddress AVEC UNE ADRESSE EMAIL CreateAppSipAccountWithEmail createAppSipAccountTitle CRÉER UN COMPTE %1 confirmAction CRÉER usernameLabel Nom d'utilisateur emailLabel Email passwordLabel Mot de passe passwordConfirmationLabel Confirmation du mot de passe passwordConfirmationError Les mots de passe ne correspondent pas. quitWarning Votre compte a été créé mais il n'a pas été validé. Êtes-vous sûr de vouloir quitter cette vue ? displayNameLabel Nom d'affichage (optionnel) CreateAppSipAccountWithPhoneNumber createAppSipAccountTitle CRÉER UN COMPTE %1 countryLabel Pays phoneNumberLabel Numéro de téléphone usernameLabel Nom d'utilisateur displayNameLabel Nom d'affichage (optionnel) confirmAction CRÉER quitWarning Votre compte a été créé mais il n'a pas été validé. Si vous quittez cette vue, vous devrez ajouter et valider manuellement votre compte dans les 24 heures. DroppableTextArea fileChooserTitle Merci de choisir un ou plusieurs fichiers dropYourAttachment Déposez votre pièce jointe attachmentTooltip Envoyer un fichier Event incomingCall Appel entrant outgoingCall Appel sortant declinedIncomingCall Appel entrant décliné declinedOutgoingCall Appel sortant décliné endedCall Fin d'appel missedIncomingCall Appel entrant manqué missedOutgoingCall Appel sortant sans réponse FetchRemoteConfiguration confirmAction TÉLÉCHARGER fetchRemoteConfigurationTitle TÉLÉCHARGER UNE CONFIGURATION urlLabel URL remoteProvisioningError Impossible d'utiliser cette URL de configuration. remoteProvisioningUpdateDescription Voulez-vous redémarrer maintenant pour prendre en compte ces modifications ? HistoryView removeAllEntriesDescription Êtes-vous sûr de vouloir supprimer cet historique ? tooltipContactEdit Editer le contact tooltipContactAdd Ajouter le contact cleanHistory Supprimer l'historique Home howToDescription Besoin d'aide sur l'utilisation de %1 ? howToTitle COMMENT UTILISER %1 inviteDescription Inviter vos amis à utiliser %1. inviteTitle INVITER VOS AMIS accountAssistantDescription Créer ou gérer votre compte %1. accountAssistantTitle ASSISTANT DE COMPTE assistantButton ASSISTANT showTooltips Voir les bulles d'aides. inviteButton INVITER Incall acceptVideoDescription Votre correspondant souhaite ajouter la vidéo. pendingRequestLabel Merci de patienter, une requête est en attente. securedStringFormat L'appel est chiffré avec: %1. callNotSecured Appel non chiffré. takeSnapshotLabel Prendre une capture d'écran. startRecordingLabel Commencer un enregistrement. stopRecordingLabel Stopper un enregistrement. IncallFullscreenWindow takeSnapshotLabel Prendre une capture d'écran. startRecordingLabel Commencer un enregistrement. stopRecordingLabel Stopper un enregistrement. InviteFriends enterEmailLabel Adresse email de votre ami messageLabel Message cancel ANNULER confirm CONFIRMER inviteFriendsTitle Inviter des amis defaultMessage %1 souhaite vous inviter sur %2 ! defaultSubject Invitation %1 forcedMessage Téléchargez l’application sur votre ordinateur et appelez vos amis ou envoyez-leur un message gratuitement. Cliquez ici : <a href="%1">%1</a> MainWindow mainSearchBarPlaceholder Chercher un contact, appeler ou envoyer un message... homeEntry ACCUEIL contactsEntry CONTACTS autoAnswerStatus auto smartSearchBarTooltip Utilisez la barre de recherche intelligente pour lancer des appels audio et vidéo, envoyer un message ou ajouter un contact. Entrez simplement l'adresse SIP ou le nom d'utilisateur de votre contact. newConferenceButton Démarrer une conférence MainWindowMenuBar settings Préférences about À propos quit Quitter MainWindowTopMenuBar settings Options about A propos quit Quitter ManageAccounts ok OK selectPresenceLabel Statut de présence selectAccountLabel Compte principal Message menuCopy Copier menuPlayMe Joue-moi ! MultimediaParameters ok OK Notifier newVersionAvailable Une nouvelle version (%1) est disponible ! newFileMessage Pièce jointe reçue ! OnlineInstallerDialog confirm CONFIRM onlineInstallerExtractingDescription Extraction de %1... onlineInstallerDownloadingDescription Téléchargement de %1... onlineInstallerFinishedDescription Installation de %1 terminée ! onlineInstallerFailedDescription L'installation de %1 a échoué ! OutgoingMessage messageError Erreur messageRead Lu messageDelivered Délivré Presence presenceOnline En ligne presenceBusy Occupé presenceDoNotDisturb Ne pas déranger presenceOffline Hors-ligne SettingsAdvanced logsTitle Logs logsFolderLabel Dossier des logs sendLogs ENVOYER LOGS logsUploadUrlLabel Url du serveur de logs logsUploadFailed L'envoi des logs a échoué. logsEnabledLabel Activer les logs cleanLogs SUPPRIMER LOGS cleanLogsDescription Voulez-vous vraiment supprimer tous les logs ? developerSettingsTitle Mode développeur developerSettingsEnabledLabel Activer le mode développeur logsMailerFailed Message when Linphone try to open a mailer to send logs, after uploading them to the server (%1 would be the upload url) Impossible de trouver un logiciel de mail. Les logs ont été uploadés sur %1 logsMailerSuccess Les logs ont été uploadé sur %1 SettingsAudio audioTitle Paramètres audio playbackDeviceLabel Périphérique d'écoute captureDeviceLabel Périphérique de capture ringerDeviceLabel Périphérique de sonnerie ringLabel Sonnerie echoCancellationLabel Activer l'annulation d'écho audioCodecsTitle Codecs audio showAudioCodecsLabel Afficher les codecs audio playbackGainLabel Gain de lecture captureGainLabel Gain de capture audioTestLabel Niveau micro audioSettingsInCallWarning Appel en cours: certains paramètres sont inaccessibles SettingsCallsChat fileServerLabel Serveur de partage encryptWithLimeLabel Chiffrer avec LIME limeDisabled Désactivé limeRequired Obligatoire limePreferred Préféré chatTitle Chat callsTitle Appels encryptionLabel Chiffrement noEncryption Aucun autoAnswerLabel Répondre automatiquement autoAnswerDelayLabel Délai (en ms) autoAnswerWithVideoLabel Répondre autom. (avec vidéo) chatEnabledLabel Activer le chat callRecorderEnabledLabel Activer l'enregistrement d'appel chatNotificationSoundEnabledLabel Activer le son des notifications chatNotificationSoundLabel Son des notifications conferenceEnabledLabel Activer la conférence contactsTitle Contacts contactsEnabledLabel Activer les contacts muteMicrophoneEnabledLabel Autoriser la désactivation du microphone outgoingCallsEnabledLabel Activer les appels sortants showTelKeypadAutomaticallyLabel Afficher le clavier tél. automatiquement automaticallyRecordCallsLabel Enregister auto. les appels keepCallsWindowInBackgroundLabel Fenêtre d'appels en tâche de fond callPauseEnabledLabel Autoriser la mise en pause encryptionMandatoryLabel Chiffrement obligatoire SettingsNetwork sendDtmfsLabel Méthode d'envoi des DTMFs allowIpV6Label Autoriser IPv6 transportTitle Transport natAndFirewallTitle NAT et Pare-feu enableIceLabel Activer ICE stunServerLabel Serveur STUN/TURN enableTurnLabel Activer TURN turnUserLabel Utilisateur TURN turnPasswordLabel Mot de passe TURN networkProtocolAndPortsTitle Protocole réseau et ports sipUdpPortLabel Port d'écoute SIP UDP sipTcpPortLabel Port d'écoute SIP TCP audioRtpUdpPortLabel Port Audio RTP UDP videoRtpUdpPortLabel Port Vidéo RTP UDP dscpFieldsTitle Champs DSCP sipFieldLabel SIP audioRtpStreamFieldLabel Flux RTP audio videoRtpStreamFieldLabel Flux RTP vidéo bandwidthControlTitle Gestion de la bande passante downloadSpeedLimitLabel Limite de débit descendant en Kbit/sec uploadSpeedLimitLabel Limite de débit montant en Kbit/sec enableAdaptiveRateControlLabel Activer le contrôle de débit adaptif presenceTitle Présence rlsUriLabel Utiliser l'URI RLS rlsUriAuto AUTO rlsUriDisabled JAMAIS showNetworkSettingsLabel Afficher les paramètres réseaux generalTitle Général SettingsSipAccounts defaultIdentityTitle Identité par défaut defaultUsernameLabel Nom d'utilisateur defaultSipAddressLabel Adresse SIP proxyAccountsTitle Comptes SIP eraseAllPasswords EFFACER LES MOTS DE PASSE addAccount AJOUTER UN COMPTE editHeader Éditer deleteHeader Supprimer deleteAccountDescription Êtes-vous sûr de vouloir supprimer ce compte ? eraseAllPasswordsDescription Êtes-vous sûr de vouloir supprimer tous vos mots de passe ? defaultDisplayNameLabel Nom d'affichage assistantTitle Assistant createAppSipAccountEnabledLabel Activer la création de compte useAppSipAccountEnabledLabel Activer l'utilisation de compte useOtherSipAccountEnabledLabel Activer l'utilisation générique de compte fetchRemoteConfigurationEnabledLabel Activer le téléchargement de conf. assistantSupportsPhoneNumbersLabel Supporter les numéros de tél. SettingsSipAccountsEdit sipAddressLabel Adresse SIP transportLabel Transport serverAddressLabel Adresse du serveur SIP registrationDurationLabel Durée d'enregistrement routeLabel Route contactParamsLabel Paramètres de contact publishPresenceLabel Publier la présence avpfIntervalLabel Intervalle standard RTCP AVPF (sec) registerEnabledLabel S'enregistrer avpfEnabledLabel Activer AVPF cancel ANNULER confirm CONFIRMER invalidSipAddress Adresse SIP invalide. invalidServerAddress Adresse du serveur invalide. invalidRoute Route invalide. enableIceLabel Activer ICE stunServerLabel Serveur STUN/TURN enableTurnLabel Activer TURN turnUserLabel Utilisateur TURN turnPasswordLabel Mot de passe TURN natAndFirewallTitle NAT et Pare-feu mainSipAccountSettingsTitle Paramètres principaux du compte SIP SettingsUi pathsTitle Chemins savedScreenshotsLabel Dossier des captures d'écran savedCallsLabel Dossier des captures d'appels languagesTitle Langues languagesLabel Langue systemLocale Locale du système cleanAvatars SUPPRIMER LES AVATARS cleanAvatarsDescription Voulez-vous vraiment supprimer tous les avatars ? downloadLabel Dossier des téléchargements setLocaleDescription Voulez-vous redémarrer maintenant pour prendre en compte ces modifications ? otherTitle Divers exitOnCloseLabel Quitter à la fermeture de fenêtre dataTitle Données autoStartLabel Démarrer auto. l'app SettingsVideo videoInputDeviceLabel Périphérique de capture vidéo videoFramerateLabel Images/s videoCaptureTitle Paramètres de capture vidéo videoPresetLabel Profil vidéo presetDefault Défaut presetHighFps Fluide presetCustom Personnalisé videoSizeLabel Définition videoCodecsTitle Codecs vidéo showCameraPreview APERÇU DE LA VIDÉO showVideoCodecsLabel Afficher les codecs vidéo videoSettingsInCallWarning Appel vidéo en cours: certains paramètres ne sont pas disponibles. SettingsVideoPreview confirm VALIDER SettingsWindow settingsTitle Paramètres sipAccountsTab Comptes SIP audioTab Audio videoTab Vidéo callsAndChatTab Appels et Chat networkTab Réseau uiTab Interface Utilisateur validButton OK uiAdvanced Avancé SmartSearchBar addContact AJOUTER CE CONTACT Timeline timelineTitle Précédemment UseAppSipAccount confirmAction UTILISER useAppSipAccountTitle UTILISER UN COMPTE %1 useUsernameToLogin Utiliser un nom d'utilisateur et mot de passe plutôt que votre numéro de téléphone. quitWarning Votre compte a été créé mais il n'a pas été validé. Êtes-vous sûr de vouloir quitter cette vue ? UseAppSipAccountWithPhoneNumber countryLabel Pays phoneNumberLabel Numéro de téléphone UseAppSipAccountWithUsername usernameLabel Nom d'utilisateur passwordLabel Mot de passe UseOtherSipAccount confirmAction UTILISER useOtherSipAccountTitle UTILISER UN COMPTE SIP usernameLabel Nom d'utilisateur displayNameLabel Nom d'affichage (optionnel) sipDomainLabel Domaine SIP passwordLabel Mot de passe transportLabel Transport addOtherSipAccountError Impossible d'ajouter ce compte. ZrtpTokenAuthentication confirmSas Confirmez le SAS suivant avec votre interlocuteur. codeA Dites : codeB Votre interlocuteur devrait dire : deny REFUSER accept CONFIRMER country Afghanistan Afghanistan Albania Albanie Algeria Algérie AmericanSamoa Samoa américaines Andorra Andorre Angola Angola Anguilla Anguilla AntiguaAndBarbuda Antigua-et-Barbuda Argentina Argentine Armenia Arménie Aruba Aruba Australia Australie Austria Autriche Azerbaijan Azerbaïdjan Bahamas Bahamas Bahrain Bahreïn Bangladesh Bangladesh Barbados Barbade Belarus Bélarus Belgium Belgique Belize Belize Benin Bénin Bermuda Bermudes Bhutan Bhoutan Bolivia Bolivie BosniaAndHerzegowina Bosnie-Herzégovine Botswana Botswana Brazil Brésil Brunei Brunei Bulgaria Bulgarie BurkinaFaso Burkina Faso Burundi Burundi Cambodia Cambodge Cameroon Cameroun Canada Canada CapeVerde Cap-Vert CaymanIslands Îles Caïmans CentralAfricanRepublic République centrafricaine Chad Tchad Chile Chili China Chine Colombia Colombie Comoros Comores PeoplesRepublicOfCongo République du Congo DemocraticRepublicOfCongo République démocratique du Congo CookIslands Îles Cook CostaRica Costa Rica IvoryCoast Côte d'Ivoire Croatia Croatie Cuba Cuba Cyprus Chypre CzechRepublic République tchèque Denmark Danemark Djibouti Djibouti Dominica Dominique DominicanRepublic République Dominicaine Ecuador Équateur Egypt Égypte ElSalvador El Salvador EquatorialGuinea Guinée équatoriale Eritrea Érythrée Estonia Estonie Ethiopia Éthiopie FalklandIslands Îles Falkland FaroeIslands Îles Féroé Fiji Fidji Finland Finlande France France FrenchGuiana Guyane française FrenchPolynesia Polynésie française Gabon Gabon Gambia Gambie Georgia Géorgie Germany Allemagne Ghana Ghana Gibraltar Gibraltar Greece Grèce Greenland Groenland Grenada Grenade Guadeloupe Guadeloupe Guam Guam Guatemala Guatemala Guinea Guinée GuineaBissau Guinée Bissau Guyana Guyana Haiti Haïti Honduras Honduras HongKong Hong Kong Hungary Hongrie Iceland Islande India Inde Indonesia Indonésie Iran Iran Iraq Irak Ireland Irlande Israel Israël Italy Italie Jamaica Jamaïque Japan Japon Jordan Jordanie Kazakhstan Kazakhstan Kenya Kenya Kiribati Kiribati DemocraticRepublicOfKorea République démocratique de Corée RepublicOfKorea République de Corée Kuwait Koweït Kyrgyzstan Kirghizistan Laos Laos Latvia Lettonie Lebanon Liban Lesotho Lesotho Liberia Liberia Libya Libye Liechtenstein Liechtenstein Lithuania Lituanie Luxembourg Luxembourg Macau Macao Macedonia Macédoine Madagascar Madagascar Malawi Malawi Malaysia Malaisie Maldives Maldives Mali Mali Malta Malte MarshallIslands Îles Marshall Martinique Martinique Mauritania Mauritanie Mauritius Maurice Mayotte Mayotte Mexico Mexique Micronesia Micronésie Moldova Moldavie Monaco Monaco Mongolia Mongolie Montenegro Monténégro Montserrat Montserrat Morocco Maroc Mozambique Mozambique Myanmar Myanmar Namibia Namibie NauruCountry Nauru Nepal Népal Netherlands Pays-Bas NewCaledonia Nouvelle-Calédonie NewZealand Nouvelle-Zélande Nicaragua Nicaragua Niger Niger Nigeria Nigeria Niue Nioué NorfolkIsland Île Norfolk NorthernMarianaIslands Îles Mariannes du Nord Norway Norvège Oman Oman Pakistan Pakistan Palau Palau PalestinianTerritories Territoires palestiniens Panama Panama PapuaNewGuinea Papouasie-Nouvelle-Guinée Paraguay Paraguay Peru Pérou Philippines Philippines Poland Pologne Portugal Portugal PuertoRico Porto Rico Qatar Qatar Reunion Réunion Romania Roumanie RussianFederation Fédération de Russie Rwanda Rwanda SaintHelena Sainte-Hélène SaintKittsAndNevis Saint-Kitts-et-Nevis SaintLucia Sainte-Lucie SaintPierreAndMiquelon Saint-Pierre-et-Miquelon SaintVincentAndTheGrenadines Saint-Vincent-et-les Grenadines Samoa Samoa SanMarino Saint-Marin SaoTomeAndPrincipe São Tomé et Principe SaudiArabia Arabie Saoudite Senegal Sénégal Serbia Serbie Seychelles Seychelles SierraLeone Sierra Leone Singapore Singapour Slovakia Slovaquie Slovenia Slovénie SolomonIslands Îles Salomon Somalia Somalie SouthAfrica Afrique du Sud Spain Espagne SriLanka Sri Lanka Sudan Soudan Suriname Suriname Swaziland Swaziland Sweden Suède Switzerland Suisse Syria Syrie Taiwan Taïwan Tajikistan Tadjikistan Tanzania Tanzanie Thailand Thaïlande Togo Togo Tokelau Tokélaou Tonga Tonga TrinidadAndTobago Trinité-et-Tobago Tunisia Tunisie Turkey Turquie Turkmenistan Turkménistan TurksAndCaicosIslands Îles Turques et Caïques Tuvalu Tuvalu Uganda Ouganda Ukraine Ukraine UnitedArabEmirates Émirats arabes unis UnitedKingdom Royaume-Uni UnitedStates Etats Unis Uruguay Uruguay Uzbekistan Ouzbékistan Vanuatu Vanuatu Venezuela Venezuela Vietnam Vietnam WallisAndFutunaIslands Îles Wallis et Futuna Yemen Yémen Zambia Zambie Zimbabwe Zimbabwe linphone-utils downloadCodecDescription Voulez-vous installer %1 (%2) ? linphone-desktop-4.2.5/linphone-app/assets/languages/hu.ts000066400000000000000000002466641376717241300236700ustar00rootroot00000000000000 About ok Rendben ActivateAppSipAccountWithEmail activateAppSipAccount %1 fiók aktiválása confirmAction Aktiválása activationSteps Fiókja aktiválásához: kövesse az utasításokat, amelyeket a(z) %1 küldtünk, majd kattintson az alábbiakra. ActivateAppSipAccountWithPhoneNumber activateAppSipAccount %1 fiók aktiválása confirmAction Aktiválása activationSteps Az ellenőrzési kódot tartalmazó SMS-t elküldtük a(z) %1-nek. A telefonszám ellenőrzésének befejezéséhez kérjük, írja be az alábbi négyjegyű kódot. App commandLineOptionVerbose küldjön naplót a stdout-hez néhány hibakeresési információ futtatás közben commandLineOptionConfig adja meg a kívánt %1 konfigurációs fájl használata applicationDescription A szabad (ingyenes) SIP videótelefon. commandLineOptionIconified indítsa el a tálcán, ne jelenítse meg a fő felületet commandLineOptionConfigArg fájl commandLineOptionHelp Súgó megjelenítése commandLineOptionVersion az alkalmazás verziójának megjelenítése commandLineOptionCliHelp megjeleníti a súgó menüt a(z) %1 CLI-vel történő használatához commandLineDescription küldjön megrendelést az alkalmazás számára a parancssornak restore Visszaállítás quit Kilépés settings Beállítások about A Linphone névjegye AssistantAbstractView back Vissza AssistantHome useAppSipAccount %1 fiók használata useOtherSipAccount SIP fiók használata fetchRemoteConfiguration Távoli konfiguráció lekérése homeTitle Isten hozott! homeDescription Ez a segéd segít a SIP fiók konfigurálásában és használatában. createAppSipAccount Készítsen egy %1 fiók AssistantModel loginWithUsernameFailed Bejelentkezés sikertelen. Kérjük, ellenőrizze felhasználónevét/jelszavát. usernameStatusTooShort Túl rövid! (legalább %1 karakter) usernameStatusTooLong Túl hosszú! (legfeljebb %1 karakter) usernameStatusInvalidCharacters Érvénytelen karaktereket észleltünk. (regex: `%1`) usernameStatusInvalid Érvénytelen felhasználónév. passwordStatusTooShort Túl rövid! (legalább %1 karakter) passwordStatusTooLong Túl hosszú! (legfeljebb %1 karakter) passwordStatusInvalidCharacters Érvénytelen karaktereket észleltünk. (regex: `%1`) passwordStatusMissingCharacters Hiányzó karakterek: „%1”. requestFailed Nem sikerült elküldeni a kérelmet. emailStatusMalformed Helytelen e-mail cím. emailStatusMalformedInvalidCharacters Helytelen e-mail cím vagy érvénytelen karakterek. cannotSendSms Kiszolgálóhiba: nem lehet SMS-t küldeni. accountAlreadyExists Ez a fiók már létezik. smsActivationFailed Az SMS aktiválása sikertelen! emailActivationFailed Kérjük, ellenőrizze, hogy érvényesítette-e fiókját, vagy próbálja újra. phoneNumberStatusInvalid Érvénytelen telefonszám! phoneNumberStatusTooShort Túl rövid! phoneNumberStatusTooLong Túl hosszú! phoneNumberStatusInvalidCountryCode Érvénytelen országkód! loginWithPhoneNumberFailed Bejelentkezés sikertelen. Kérjük, ellenőrizze telefonszámát. unableToAddAccount Nem sikerült hozzáadni ezt a fiókot. AuthenticationRequest cancel Mégse confirm Bejelentkezés identityLabel Felhasználó passwordLabel Jelszó authenticationRequestDescription Nem sikerült a hitelesítés. Kérjük, ellenőrizze a jelszavát. userIdLabel Felhasználói azonosítás (választható) realmLabel Tartomány CallModel callStatsCodec Kodek callStatsUploadBandwidth Feltöltési sávszélesség callStatsDownloadBandwidth Letöltési sávszélesség callStatsEstimatedDownloadBandwidth Becsült letöltési sávszélesség callStatsIceState ICE állapot callStatsIpFamily IP család callStatsSenderLossRate Feladó adatvesztési aránya callStatsReceiverLossRate Címzett adatvesztési arány callStatsJitterBuffer Csúszás puffer callStatsSentVideoDefinition Küldött videó meghatározás callStatsReceivedVideoDefinition Fogadott videó meghatározás iceStateNotActivated Nincs aktiválva iceStateFailed Sikertelen iceStateInProgress Folyamatban iceStateReflexiveConnection Reflexív kapcsolat iceStateHostConnection Gép kapcsolat iceStateRelayConnection Közvetítő kapcsolat iceStateInvalid Érvénytelen callErrorDeclined A távoli fél elutasította a hívást. callErrorNotFound Távoli fél nem található. callErrorBusy Távoli fél elfoglalt. callErrorNotAcceptable A távoli fél nem fogadhatja el a hívást. callStatsReceivedFramerate Fogadott képkockasebesség callStatsSentFramerate Küldött képkockasebesség CallSipAddress cancel Mégse callSipAddressDescription Új hívás indítása. CallStatistics audioStatsLabel Hang videoStatsLabel Videó CallTransfer cancel Mégse callTransferDescription Szeretné átirányítani a hívást? Calls acceptAudioCall Hanghívás elfogadása acceptVideoCall Videohívás elfogadása terminateCall Hívás befejezése resumeCall Hívás folytatása transferCall Hívásátirányítása callPause Hívástartás CallsWindow callsTitle Hívások acceptClosingDescription Biztos benne, hogy be kívánja fejezni az összes hívást? Chat newMessagePlaceholder Írja be az üzenetét noFileTransferUrl Nem sikerült elküldeni a fájlt. A kiszolgáló URL-je nincs konfigurálva. isComposing %1 gépel… Cli appCliDescription A(z) %1 alkalmazás vezérlésének módja a parancssorokon keresztül. uriCommandLineSyntax %1 <sip-address>?method=<method>([&<argument>=<base64-value>]*) cliCommandLineSyntax %1 "<method> ([<argument>=<value>]*)" commandsName parancsok listája: showFunctionDescription Alkalmazás főablakának megjelenítése. callFunctionDescription Hívást kezdeményez a sip-address. initiateConferenceFunctionDescription Konferencia kezdeményezése. joinConferenceFunctionDescription Csatlakozzon a SIP-cím által rendezett konferenciához megjelenítendő névként. Ha kapcsolódik egy proxy-konfigurátorhoz, olvassa el a join-conference-as című részt. joinConferenceAsFunctionDescription Csatlakozzon a SIP-cím által üzemeltetett konferenciához, mint a vendég-sip-cím. Ha nem csatlakozik proxy-konfigurátorhoz, olvassa el a csatlakozási konferencia részt. CodecsViewer codecMime Név codecEncoderDescription Leírás codecEncoderClockRate Sebesség (Hz) codecBitrate Bitsebesség (Kbit/mp) codecRecvFmtp Paraméterek codecStatus Állapot Conference conferenceTitle Konferencia ConferenceControls conference Konferencia ConferenceManager conferenceManagerDescription Kezelje a konferencia résztvevőit. cancel Mégse confirm Indítás ConfirmDialog cancel Mégse confirm Megerősít ContactEdit removeContactDescription Tényleg eltávolítja ezt a névjegyet a címjegyzékből? sipAccounts SIP fiók(ok) address Cím emails E-mail(ek) webSites Honlap(ok) avatarChooserTitle Avatár kiválasztása companies Cégek save Mentés cancel Mégse sipAccountsPlaceholder SIP fiók companiesPlaceholder Cég emailsPlaceholder E-mail webSitesPlaceholder Honlap street Utca postalCode Irányítószám country Ország locality Helyiség abortEditDescriptionText Biztosan törli a névjegy változtatását? tooltipShowConversation Beszélgetés megjelenítése Contacts searchContactPlaceholder Névjegy keresése selectAllContacts Összes selectConnectedContacts Kapcsolódva addContact Névjegy hozzáadása removeContactDescription Tényleg eltávolítja ezt a névjegyet a címjegyzékből? Conversation displayCallsAndMessages Összes displayCalls Hívások displayMessages Üzenetek removeAllEntriesDescription Biztosan törölni kívánja ezt az előzményt? tooltipContactEdit Kapcsolat szerkesztése tooltipContactAdd Kapcsolat hozzáadása cleanHistory Előzmények törlése CreateAppSipAccount createAppSipAccountDescription Hogyan szeretné létrehozni a fiókját? createAppSipAccountTitle %1 fiók létrehozása withPhoneNumber Telefonszámmal withEmailAddress E-mail címmel CreateAppSipAccountWithEmail createAppSipAccountTitle %1 fiók létrehozása confirmAction Létrehozás usernameLabel Felhasználónév emailLabel E-mail passwordLabel Jelszó passwordConfirmationLabel Jelszó megerősítése passwordConfirmationError A megadott jelszavak nem egyeznek. quitWarning Fiókját létrehozta, de még nem hitelesítette. Biztosan le szeretne lépni erről a nézetről? displayNameLabel Megjelenítendő név (választható) CreateAppSipAccountWithPhoneNumber createAppSipAccountTitle %1 fiók létrehozása countryLabel Ország phoneNumberLabel Telefonszám usernameLabel Felhasználónév displayNameLabel Megjelenítendő név (választható) confirmAction Létrehozás quitWarning Fiókját létrehozta, de még nem hitelesítette. Ha kilép ebből a nézetből, akkor 24 órán belül kézzel kell hozzáadnia és érvényesítenie a fiókját. DroppableTextArea fileChooserTitle Válasszon egy vagy több fájlt dropYourAttachment Adja hozzá ide a mellékletet attachmentTooltip Fájl küldése Event incomingCall Bejövő hívás outgoingCall Kimenő hívás declinedIncomingCall Bejövő hívás elutasítása declinedOutgoingCall Kimenő hívás elutasítása endedCall Befejezett hívás missedIncomingCall Nem fogadott bejövő hívás missedOutgoingCall Nem fogadott kimenő hívás FetchRemoteConfiguration confirmAction Lekérés fetchRemoteConfigurationTitle Távoli konfiguráció lekérése urlLabel URL remoteProvisioningError Nem sikerült beállítani ezt a távoli létesítési URI-t. remoteProvisioningUpdateDescription Az alkalmazás újraindítása szükséges. Szeretné most újraindítani? HistoryView removeAllEntriesDescription Biztosan törölni kívánja ezt az előzményt? tooltipContactEdit Kapcsolat szerkesztése tooltipContactAdd Kapcsolat hozzáadása cleanHistory Előzmények törlése Home howToDescription Segítségre van szüksége a(z) %1 használatához? howToTitle Hogyan kell %1 használni inviteDescription Hívd meg ismerőseidet a %1-ra. inviteTitle Hívd meg a ismerőseidet accountAssistantDescription A(z) %1 fiók létrehozása vagy kezelése. accountAssistantTitle Fióksegéd assistantButton Segéd showTooltips Buboréksúgók megjelenítése inviteButton Meghívás Incall acceptVideoDescription Kapcsolattartója szeretné bekapcsolni a videót. pendingRequestLabel Kérjük, várjon, egy kérés függőben van. securedStringFormat A hívás titkosítva: %1. callNotSecured A hívás nincs titkosítva. takeSnapshotLabel Pillanatkép készítése. startRecordingLabel Felvétel megindítása. stopRecordingLabel A felvétel leállítása. IncallFullscreenWindow takeSnapshotLabel Pillanatkép készítése. startRecordingLabel Felvétel megindítása. stopRecordingLabel A felvétel leállítása. InviteFriends enterEmailLabel Ismerős e-mail címe messageLabel Üzenet cancel Mégse confirm Megerősít inviteFriendsTitle Ismerősök meghívása defaultMessage %1 partnerfelkérései a %2-n! defaultSubject %1 meghívás forcedMessage Töltse le az alkalmazást a számítógépén, és kezdje el ingyen hívni és csevegni a felhasználókkal. Kattintson ide: <a href="%1">%1</a> MainWindow mainSearchBarPlaceholder Keressen névjegyet, indítson hívást vagy csevegést… homeEntry Kezdőlap contactsEntry Névjegyek autoAnswerStatus önműködő smartSearchBarTooltip Az intelligens keresősáv segítségével közvetlenül kezdeményezheti audio- és videohívásokat, küldhet üzenetet vagy új névjegyet adhat hozzá. Csak írja be ismerőse SIP-címét vagy felhasználónevét. newConferenceButton Konferencia-beszélgetés indítása MainWindowMenuBar settings Beállítások about A Linphone névjegye quit Kilépés MainWindowTopMenuBar settings Beállítások about Ról ről quit Kilépés ManageAccounts ok Rendben selectPresenceLabel Jelenléti állapot selectAccountLabel Aktív fiók Message menuCopy Másolás menuPlayMe Lejátszás MultimediaParameters ok Rendben Notifier newVersionAvailable Egy új frissítés (%1) érhető el! newFileMessage Új melléklet érkezett! OnlineInstallerDialog confirm Megerősít onlineInstallerExtractingDescription %1 kicsomagolása… onlineInstallerDownloadingDescription %1 letöltése… onlineInstallerFinishedDescription A(z) %1 sikeresen telepítve lett! onlineInstallerFailedDescription A(z) %1 telepítése nem sikerült! OutgoingMessage messageError Hiba messageRead Olvasott messageDelivered Kézbesítve Presence presenceOnline Elérhető presenceBusy Elfoglalt presenceDoNotDisturb Ne zavarjanak presenceOffline Kapcsolat nélküli SettingsAdvanced logsTitle Naplók logsFolderLabel Naplómappa sendLogs Naplók küldése logsUploadUrlLabel Naplók feltöltési kiszolgáló URL-je logsUploadFailed A naplók feltöltése nem sikerült. logsEnabledLabel Naplók engedélyezése cleanLogs Napló kitakarítása cleanLogsDescription Biztosan eltávolítja az összes naplót? developerSettingsTitle Fejlesztői beállítások developerSettingsEnabledLabel Fejlesztői beállítások engedélyezése logsMailerFailed Message when Linphone try to open a mailer to send logs, after uploading them to the server (%1 would be the upload url) A Mailer nem található, de a naplók feltöltődtek a %1 logsMailerSuccess A naplókat feltöltötték a %1 SettingsAudio audioTitle Hang paraméterek playbackDeviceLabel Lejátszóeszköz captureDeviceLabel Felvevőeszköz ringerDeviceLabel Csörgetés ringLabel Csörög echoCancellationLabel Visszhangkioltás engedélyezése audioCodecsTitle Hang kodekek showAudioCodecsLabel Hang kodekek megjelenítése playbackGainLabel Lejátszás nyeresége captureGainLabel Rögzítés nyereség audioTestLabel Felvételi szint audioSettingsInCallWarning Hanghívás folyamatban: egyes beállítások nem érhetők el. SettingsCallsChat fileServerLabel Fájlkiszolgáló encryptWithLimeLabel LIME titkosítás limeDisabled Letiltva limeRequired Kötelező limePreferred Elsődleges chatTitle Csevegés callsTitle Hívások encryptionLabel Titkosítás noEncryption Nincs autoAnswerLabel Önműködő válasz autoAnswerDelayLabel Késés (ms) autoAnswerWithVideoLabel Önműködő válasz (videóval) chatEnabledLabel Csevegés engedélyezése callRecorderEnabledLabel Hívásfelvétel engedélyezése chatNotificationSoundEnabledLabel Értesítési hang engedélyezése chatNotificationSoundLabel Értesítési hang conferenceEnabledLabel Konferencia engedélyezése contactsTitle Névjegyek contactsEnabledLabel Névjegyek engedélyezése muteMicrophoneEnabledLabel A mikrofon némításának engedélyezése outgoingCallsEnabledLabel Kimenő hívások engedélyezése showTelKeypadAutomaticallyLabel A telefonbillentyűzet önműködően megjelenítése automaticallyRecordCallsLabel Hívások önműködő felvétele keepCallsWindowInBackgroundLabel Tartsa a hívások ablakot a háttérben callPauseEnabledLabel A hívástartás engedélyezve encryptionMandatoryLabel A titkosítás kötelező SettingsNetwork sendDtmfsLabel DTMF küldési eljárás allowIpV6Label IPv6 engedélyezése transportTitle Szállítás natAndFirewallTitle NAT és tűzfal enableIceLabel ICE engedélyezése stunServerLabel STUN/TURN kiszolgáló enableTurnLabel TURN engedélyezése turnUserLabel TURN felhasználó turnPasswordLabel TURN jelszó networkProtocolAndPortsTitle Hálózati protokoll és kikötők sipUdpPortLabel SIP UDP kikötő sipTcpPortLabel SIP TCP kikötő audioRtpUdpPortLabel Hang RTP UDP kikötő videoRtpUdpPortLabel Videó RTP UDP kikötő dscpFieldsTitle DSCP mezők sipFieldLabel SIP audioRtpStreamFieldLabel Hang RTP adatfolyam videoRtpStreamFieldLabel Videó RTP adatfolyam bandwidthControlTitle Sávszélesség-vezérlés downloadSpeedLimitLabel Letöltés sebességkorlátozása (Kbit/mp) uploadSpeedLimitLabel Feltöltési sebességkorlátozása (Kbit/mp) enableAdaptiveRateControlLabel Adaptív sebességszabályozás engedélyezése presenceTitle Jelenlét rlsUriLabel RLS URI használata rlsUriAuto Önműködő rlsUriDisabled Soha showNetworkSettingsLabel Hálózati beállítások megjelenítése generalTitle Általános SettingsSipAccounts defaultIdentityTitle Alapértelmezett azonosság defaultUsernameLabel Felhasználónév defaultSipAddressLabel SIP cím proxyAccountsTitle Proxyfiókok eraseAllPasswords Jelszavak törlése addAccount Fiók hozzáadása editHeader Szerkesztés deleteHeader Törlés deleteAccountDescription Biztosan törölni kívánja ezt a fiókot? eraseAllPasswordsDescription Biztos, hogy eltávolítja az összes jelszavát? defaultDisplayNameLabel Megjelenítendő név assistantTitle Segéd createAppSipAccountEnabledLabel Fióklétrehozás engedélyezése useAppSipAccountEnabledLabel Fiókhasználat engedélyezése useOtherSipAccountEnabledLabel Általános fiókhasználat engedélyezése fetchRemoteConfigurationEnabledLabel Konfiguráció lekérés engedélyezése assistantSupportsPhoneNumbersLabel Támogatja a telefonszámokat SettingsSipAccountsEdit sipAddressLabel SIP cím transportLabel Szállítás serverAddressLabel SIP kiszolgáló címe registrationDurationLabel Regisztráció időtartama (mp) routeLabel Útvonal contactParamsLabel Névjegy paraméterei publishPresenceLabel Jelenlét láthatóvá tétele avpfIntervalLabel AVPF szokásos RTCP időközönként (mp) registerEnabledLabel Regisztráció avpfEnabledLabel AVPF engedélyezése cancel Mégse confirm Megerősít invalidSipAddress Érvénytelen SIP-cím. invalidServerAddress Érvénytelen kiszolgáló cím. invalidRoute Érvénytelen útvonal. enableIceLabel ICE engedélyezése stunServerLabel STUN/TURN kiszolgáló enableTurnLabel TURN engedélyezése turnUserLabel TURN felhasználó turnPasswordLabel TURN jelszó natAndFirewallTitle NAT és tűzfal mainSipAccountSettingsTitle Fő SIP fiók beállításai SettingsUi pathsTitle Utak savedScreenshotsLabel Mentett képernyőképek mappája savedCallsLabel Mentett hívások mappája languagesTitle Nyelvek languagesLabel Nyelv systemLocale Rendszer területi beállítása cleanAvatars Megtestesülés törlése cleanAvatarsDescription Biztos, hogy eltávolítja az összes megtestesülést? downloadLabel Letöltési mappa setLocaleDescription Az alkalmazás újraindítása szükséges. Szeretné most újraindítani? otherTitle Egyéb exitOnCloseLabel Alkalmazás kilépése az ablak bezárásakor dataTitle UI-adatok autoStartLabel Alkalmazás önműködő indítása SettingsVideo videoInputDeviceLabel Videó beviteli eszköz videoFramerateLabel Képkockasebesség videoCaptureTitle Videofelvétel paraméterei videoPresetLabel Videó előbeállítás presetDefault Alapértelmezett presetHighFps Magas képkockák másodpercenkénti szám presetCustom Egyéni videoSizeLabel Videó felbontás videoCodecsTitle Videó kodekek showCameraPreview Videó előnézete showVideoCodecsLabel Videó kodekek megjelenítése videoSettingsInCallWarning Videohívás folyamatban: egyes beállítások nem állnak rendelkezésre. SettingsVideoPreview confirm Rendben SettingsWindow settingsTitle Beállítások sipAccountsTab SIP fiókok audioTab Hang videoTab Videó callsAndChatTab Hívások és csevegés networkTab Hálózat uiTab Felhasználói felület validButton Rendben uiAdvanced Haladó SmartSearchBar addContact Névjegy hozzáadása Timeline timelineTitle Korábban UseAppSipAccount confirmAction Használat useAppSipAccountTitle %1 fiók használata useUsernameToLogin A telefonszám helyett használjon felhasználónevet és jelszót. quitWarning Fiókját létrehozta, de még nem hitelesítette. Biztosan le szeretne lépni erről a nézetről? UseAppSipAccountWithPhoneNumber countryLabel Ország phoneNumberLabel Telefonszám UseAppSipAccountWithUsername usernameLabel Felhasználónév passwordLabel Jelszó UseOtherSipAccount confirmAction Használat useOtherSipAccountTitle SIP fiók használata usernameLabel Felhasználónév displayNameLabel Megjelenítendő név (választható) sipDomainLabel SIP tartomány passwordLabel Jelszó transportLabel Szállítás addOtherSipAccountError Nem sikerült hozzáadni ezt a fiókot. ZrtpTokenAuthentication confirmSas Erősítse meg a következő SAS-t a társsal. codeA Mond: codeB A kapcsolattartónak el kell mondania: deny Letiltás accept Megerősít country Afghanistan Afganisztán Albania Albánia Algeria Algéria AmericanSamoa Amerikai Szamoa Andorra Andorra Angola Angola Anguilla Anguilla AntiguaAndBarbuda Antigua és Barbuda Argentina Argentína Armenia Örményország Aruba Aruba Australia Ausztrália Austria Ausztria Azerbaijan Azerbajdzsán Bahamas Bahamák Bahrain Bahrein Bangladesh Banglades Barbados Barbados Belarus Fehéroroszország Belgium Belgium Belize Belize Benin Benin Bermuda Bermuda Bhutan Bhután Bolivia Bolívia BosniaAndHerzegowina Bosznia és Hercegovina Botswana Botswana Brazil Brazília Brunei Brunei Bulgaria Bulgária BurkinaFaso Burkina Faso Burundi Burundi Cambodia Kambodzsa Cameroon Kamerun Canada Kanada CapeVerde Zöld-foki-szigetek CaymanIslands Kajmán-szigetek CentralAfricanRepublic Közép-Afrikai Köztársaság Chad Csád Chile Chile China Kína Colombia Colombia Comoros Comore-szigetek PeoplesRepublicOfCongo Kongói Népköztársaság DemocraticRepublicOfCongo Kongói Demokratikus Köztársaság CookIslands Cook-szigetek CostaRica Costa Rica IvoryCoast Elefántcsontpart Croatia Horvátország Cuba Kuba Cyprus Ciprus CzechRepublic Cseh Köztársaság Denmark Dánia Djibouti Dzsibuti Dominica Dominika DominicanRepublic Dominikai Köztársaság Ecuador Ecuador Egypt Egyiptom ElSalvador El Salvador EquatorialGuinea Egyenlítői-Guinea Eritrea Eritrea Estonia Észtország Ethiopia Etiópia FalklandIslands Falkland-szigetek FaroeIslands Feröer-szigetek Fiji Fidzsi-szigetek Finland Finnország France Franciaország FrenchGuiana Francia Guyana FrenchPolynesia Francia Polinézia Gabon Gabon Gambia Gambia Georgia Grúzia Germany Németország Ghana Ghána Gibraltar Gibraltár Greece Görögország Greenland Grönland Grenada Grenada Guadeloupe Guadeloupe Guam Guam Guatemala Guatemala Guinea Guinea GuineaBissau Bissau-Guinea Guyana Guyana Haiti Haiti Honduras Honduras HongKong Hong Kong Hungary Magyarország Iceland Izland India India Indonesia Indonézia Iran Irán Iraq Irak Ireland Írország Israel Izrael Italy Olaszország Jamaica Jamaica Japan Japán Jordan Jordánia Kazakhstan Kazahsztán Kenya Kenya Kiribati Kiribati DemocraticRepublicOfKorea Koreai Népi Demokratikus Köztársaság RepublicOfKorea Koreai Köztársaság Kuwait Kuvait Kyrgyzstan Kirgizisztán Laos Laosz Latvia Lettország Lebanon Libanon Lesotho Lesotho Liberia Libéria Libya Líbia Liechtenstein Liechtenstein Lithuania Litvánia Luxembourg Luxembourg Macau Makaó Macedonia Macedónia Madagascar Madagaszkár Malawi Malawi Malaysia Malaysia Maldives Maldív-szigetek Mali Mali Malta Málta MarshallIslands Marshall-szigetek Martinique Martinique Mauritania Mauritánia Mauritius Mauritius Mayotte Mayotte Mexico Mexikó Micronesia Mikronézia Moldova Moldova Monaco Monaco Mongolia Mongólia Montenegro Montenegró Montserrat Montserrat Morocco Marokkó Mozambique Mozambik Myanmar Myanmar Namibia Namíbia NauruCountry Nauru Nepal Nepál Netherlands Németalföld NewCaledonia Új-Kaledónia NewZealand Új-Zéland Nicaragua Nicaragua Niger Niger Nigeria Nigéria Niue Niue NorfolkIsland Norfolk-sziget NorthernMarianaIslands Észak Mariana szigetek Norway Norvégia Oman Omán Pakistan Pakisztán Palau Palau PalestinianTerritories Palesztin területek Panama Panama PapuaNewGuinea Pápua Új-Guinea Paraguay Paraguay Peru Peru Philippines Fülöp-szigetek Poland Lengyelország Portugal Portugália PuertoRico Puerto Rico Qatar Katar Reunion Reunion Romania Románia RussianFederation Orosz Föderáció Rwanda Ruanda SaintHelena Saint Helena SaintKittsAndNevis Saint Kitts és Nevis SaintLucia Saint Lucia SaintPierreAndMiquelon Saint Pierre és Miquelon SaintVincentAndTheGrenadines Saint Vincent és a Grenadine-szigetek Samoa Szamoa SanMarino San Marino SaoTomeAndPrincipe São Tomé és Príncipe SaudiArabia Szaud-Arábia Senegal Szenegál Serbia Szerbia Seychelles Seychelles SierraLeone Sierra Leone Singapore Szingapúr Slovakia Szlovákia Slovenia Szlovénia SolomonIslands Salamon-szigetek Somalia Szomália SouthAfrica Dél-Afrika Spain Spanyolország SriLanka Srí Lanka Sudan Szudán Suriname Suriname Swaziland Szváziföld Sweden Svédország Switzerland Svájc Syria Szíria Taiwan Tajvan Tajikistan Tádzsikisztán Tanzania Tanzánia Thailand Thaiföld Togo Togo Tokelau Tokelau Tonga Tonga TrinidadAndTobago Trinidad és Tobago Tunisia Tunézia Turkey Törökország Turkmenistan Türkmenisztán TurksAndCaicosIslands Turks- és Caicos-szigetek Tuvalu Tuvalu Uganda Uganda Ukraine Ukrajna UnitedArabEmirates Egyesült Arab Emírségek UnitedKingdom Egyesült Királyság UnitedStates Egyesült Államok Uruguay Uruguay Uzbekistan Üzbegisztán Vanuatu Vanuatu Venezuela Venezuela Vietnam Vietnam WallisAndFutunaIslands Wallis- és Futuna-szigetek Yemen Jemen Zambia Zambia Zimbabwe Zimbabwe linphone-utils downloadCodecDescription Szeretné letölteni a(z) %1 (%2)? linphone-desktop-4.2.5/linphone-app/assets/languages/it.ts000066400000000000000000002437651376717241300236670ustar00rootroot00000000000000 About ok OK ActivateAppSipAccountWithEmail activateAppSipAccount ATTIVA IL TUO ACCOUNT %1 confirmAction ATTIVA activationSteps per attivare il tuo account segui le istruzioni cliccando sul link: %1 ActivateAppSipAccountWithPhoneNumber activateAppSipAccount ATTIVA IL TUO ACCOUNT %1 confirmAction ATTIVA activationSteps Abbiamo inviato un SMS con un codice di convalida a %1. Per completare la verifica del numero di telefono, inserisci il codice di 4 cifre in basso. App commandLineOptionVerbose Accedi allo stdout di alcune informazioni di debug durante l'esecuzione commandLineOptionConfig specifica il file di configurazione di %1 da utilizzare applicationDescription A free (libre) SIP video-phone. commandLineOptionIconified avvia nella barra delle applicazioni, non mostrare l'interfaccia principale commandLineOptionConfigArg file commandLineOptionHelp mostra questo aiuto commandLineOptionVersion mostra la versione dell'app commandLineOptionCliHelp visualizza il menu guida per utilizzare %1 con la CLI commandLineDescription invia un comando all'applicazione tramite la riga di comando restore Ripristina quit Esci settings Preferenze about Informazioni AssistantAbstractView back INDIETRO AssistantHome useAppSipAccount USARE UN ACCOUNT %1 useOtherSipAccount USA UN ACCOUNT SIP fetchRemoteConfiguration RECUPERA UNA CONFIGURAZIONE REMOTA homeTitle BENVENUTO homeDescription Questo assistente ti aiuterà a configurare e utilizzare il tuo account sip. createAppSipAccount CREA UN ACCOUNT %1 AssistantModel loginWithUsernameFailed Accesso fallito. Controlla l'utente e la password. usernameStatusTooShort Troppo corto! (min. %1 caratteri) usernameStatusTooLong Troppo lungo! (max. %1 caratteri) usernameStatusInvalidCharacters Rilevati caratteri non validi. (regex: `%1`) usernameStatusInvalid Nome utente non valido. passwordStatusTooShort Troppo corto! (min. %1 caratteri) passwordStatusTooLong Troppo lungo! (max. %1 caratteri) passwordStatusInvalidCharacters Rilevati caratteri non validi. (regex: `%1`) passwordStatusMissingCharacters Caratteri mancanti: `%1`. requestFailed Impossibile inviare la richiesta. emailStatusMalformed Indirizzo email errato. emailStatusMalformedInvalidCharacters Indirizzo email errato o caratteri non validi. cannotSendSms Errore del server: impossibile inviare SMS. accountAlreadyExists Questo account esiste già. smsActivationFailed Attivazione SMS fallita! emailActivationFailed Verifica di aver convalidato il tuo account o riprova. phoneNumberStatusInvalid Numero di telefono non valido phoneNumberStatusTooShort Troppo corto! phoneNumberStatusTooLong Troppo lungo! phoneNumberStatusInvalidCountryCode Codice paese non valido! loginWithPhoneNumberFailed Accesso fallito. Per favore controlla il tuo numero di telefono. unableToAddAccount Impossibile aggiungere questo account. AuthenticationRequest cancel ANNULLA confirm LOGIN identityLabel Identità passwordLabel Password authenticationRequestDescription Impossibile autenticarsi. Verifica la password. userIdLabel User ID (opzionale) realmLabel Realm CallModel callStatsCodec Codec callStatsUploadBandwidth Banda di upload callStatsDownloadBandwidth Banda di download callStatsEstimatedDownloadBandwidth Banda di download stimata callStatsIceState Stato ICE callStatsIpFamily Famiglia IP callStatsSenderLossRate Tasso di perdita del mittente callStatsReceiverLossRate Tasso di perdita del ricevente callStatsJitterBuffer Buffer Jitter callStatsSentVideoDefinition Definizione del video inviata callStatsReceivedVideoDefinition Definizione del video ricevuta iceStateNotActivated Non attivato iceStateFailed Errore iceStateInProgress In carimento iceStateReflexiveConnection Connessione riflessiva iceStateHostConnection Connessione host iceStateRelayConnection Connessione relay iceStateInvalid Non valido callErrorDeclined Il destinatario ha rifiutato la chiamata. callErrorNotFound Destinatario non trovato. callErrorBusy Destinatario occupato. callErrorNotAcceptable La parte remota non può accettare la chiamata. callStatsReceivedFramerate Framerate di ricezione callStatsSentFramerate Framerate di invio CallSipAddress cancel ANNULLA callSipAddressDescription Avvia una nuova chiamata CallStatistics audioStatsLabel Audio videoStatsLabel Video CallTransfer cancel ANNULLA callTransferDescription Vuoi trasferire la chiamata? Calls acceptAudioCall ACCETTA LA CHIAMATA AUDIO acceptVideoCall ACCETTA LA CHIAMATA VIDEO terminateCall RIAGGANCIA resumeCall RIPRENDI CHIAMATA transferCall TRASFERISCI CHIAMATA callPause PAUSA CHIAMATA CallsWindow callsTitle Chiamate acceptClosingDescription Sei sicuro di voler terminare tutte le chiamate? Chat newMessagePlaceholder Inserisci il tuo messaggio noFileTransferUrl Impossibile inviare il file. URL del server non configurato. isComposing %1 sta scrivendo... Cli appCliDescription Modo per controllare l'applicazione %1 tramite riga di comando. uriCommandLineSyntax %1 <sip-address>?method=<method>([&<argument>=<base64-value>]*) cliCommandLineSyntax %1 "<method> ([<argument>=<value>]*)" commandsName lista dei comandi: showFunctionDescription Mostra la finestra principale dell'applicazione. callFunctionDescription Inizia una chiamata all'indirizzo sip. initiateConferenceFunctionDescription Inizia una conferenza. joinConferenceFunctionDescription Partecipa alla conferenza dell'indirizzo SIP con il tuo nome. Se sei connesso a un proxy, vedi 'Partecipa a conferenza come...' joinConferenceAsFunctionDescription Partecipa alla conferenza dell'indirizzo SIP con il tuo nome. Se non sei connesso a un proxy, vedi 'Partecipa a conferenza' CodecsViewer codecMime Nome codecEncoderDescription Descrizione codecEncoderClockRate Frequenza (Hz) codecBitrate Bitrate (Kbit/s) codecRecvFmtp Parametri codecStatus Status Conference conferenceTitle CONFERENZA ConferenceControls conference CONFERENZA ConferenceManager conferenceManagerDescription Gestisci i partecipanti alla tua conferenza. cancel ANNULLA confirm AVVIA ConfirmDialog cancel ANNULLA confirm CONFERMA ContactEdit removeContactDescription Vuoi veramente rimuovere questo contatto dalla tua rubrica? sipAccounts SIP ACCOUNT address INDIRIZZO emails E-MAIL(S) webSites WEB SITE(S) avatarChooserTitle Scegli il tuo avatar companies AZIENDE save SALVA cancel ANNULLA sipAccountsPlaceholder Account SIP companiesPlaceholder Azienda emailsPlaceholder Email webSitesPlaceholder Web site street Strada postalCode Codice postale country Paese locality Località abortEditDescriptionText Sei sicuro di voler annullare la modifica del contatto? tooltipShowConversation Mostra conversazione Contacts searchContactPlaceholder Cerca contatto selectAllContacts Tutti selectConnectedContacts Connesso addContact AGGIUNGI UN CONTATTO removeContactDescription Vuoi veramente rimuovere questo contatto dalla tua rubrica? Conversation displayCallsAndMessages TUTTI displayCalls CHIAMATE displayMessages MESSAGGI removeAllEntriesDescription Sei sicuro di voler cancellare questa cronologia? tooltipContactEdit Modifica contatto tooltipContactAdd Aggiungi contatto cleanHistory Cancella cronologia CreateAppSipAccount createAppSipAccountDescription Come ti piacerebbe creare il tuo account? createAppSipAccountTitle CREA UN ACCOUNT %1 withPhoneNumber CON UN NUMERO DI TELEFONO withEmailAddress CON UN INDIRIZZO E-MAIL CreateAppSipAccountWithEmail createAppSipAccountTitle CREA UN ACCOUNT %1 confirmAction CREA usernameLabel Nome utente emailLabel E-mail passwordLabel Password passwordConfirmationLabel Conferma password passwordConfirmationError Le password inserite non combaciano. quitWarning Il tuo account è stato creato ma non è ancora stato convalidato. Sei sicuro di voler uscire da questa schermata? displayNameLabel Nome visualizzato (facoltativo) CreateAppSipAccountWithPhoneNumber createAppSipAccountTitle CREA UN ACCOUNT %1 countryLabel Paese phoneNumberLabel Numero di telefono usernameLabel Nome utente displayNameLabel Nome visualizzato (facoltativo) confirmAction CREA quitWarning Il tuo account è stato creato ma non è ancora stato convalidato. Se esci da questa schermata, dovrai aggiungere e convalidare manualmente il tuo account entro 24 ore. DroppableTextArea fileChooserTitle Seleziona uno o più file dropYourAttachment Rilascia il tuo allegato attachmentTooltip Invia un file Event incomingCall Chiamata in arrivo outgoingCall Chiamata in uscita declinedIncomingCall Chiamata in arrivo rifiutata declinedOutgoingCall Chiamata in uscita rifiutata endedCall Chiamata terminata missedIncomingCall Chiamata in arrivo persa missedOutgoingCall Chiamata in uscita persa FetchRemoteConfiguration confirmAction RECUPERA fetchRemoteConfigurationTitle RECUPERA LA CONFIGURAZIONE REMOTA urlLabel URL remoteProvisioningError Impossibile impostare questo uri di provisioning remoto. remoteProvisioningUpdateDescription È necessario riavviare l'applicazione. Vuoi riavviare ora? HistoryView removeAllEntriesDescription Sei sicuro di voler cancellare questa cronologia? tooltipContactEdit Modifica contatto tooltipContactAdd Aggiungi contatto cleanHistory Cancella cronologia Home howToDescription Hai bisogno di aiuto su come utilizzare %1? howToTitle COME USARE %1 inviteDescription Invita i tuoi amici su %1. inviteTitle INVITA I TUOI AMICI accountAssistantDescription Crea o gestisci il tuo account %1. accountAssistantTitle ASSISTENTE ACCOUNT assistantButton ASSISTENTE showTooltips Mostra suggerimenti inviteButton INVITA Incall acceptVideoDescription Il tuo contatto vorrebbe passare al video. pendingRequestLabel Attendi, la richiesta è in sospeso. securedStringFormat Chiamata cifrata con: %1. callNotSecured Chiamata non cifrata. takeSnapshotLabel Fai un'istantanea. startRecordingLabel Inizia a registrare. stopRecordingLabel Ferma la registrazione. IncallFullscreenWindow takeSnapshotLabel Fai un'istantanea. startRecordingLabel Inizia a registrare. stopRecordingLabel Ferma la registrazione. InviteFriends enterEmailLabel L'indirizzo email dell'amico messageLabel Messaggio cancel ANNULLA confirm CONFERMA inviteFriendsTitle Invita gli amici defaultMessage %1 vuole invitarti su %2! defaultSubject %1 invito forcedMessage Scarica l'applicazione sul tuo computer e inizia a chiamare e chattare con gli utenti gratuitamente. Clicca: <a href="%1">%1</a> MainWindow mainSearchBarPlaceholder Cerca un contatto, avvia una chiamata o una chat... homeEntry HOME contactsEntry CONTATTI autoAnswerStatus auto smartSearchBarTooltip Usa la barra di ricerca intelligente per avviare direttamente chiamate audio e video, inviare un messaggio o aggiungere un nuovo contatto. Basta inserire l'indirizzo SIP o nome utente del tuo amico. newConferenceButton Avvia una conferenza telefonica MainWindowMenuBar settings Preferenze about Informazioni quit Esci MainWindowTopMenuBar settings Preferenze about Circa quit Provando ManageAccounts ok OK selectPresenceLabel Stato di presenza selectAccountLabel Account attivo Message menuCopy Copia menuPlayMe Avviami! MultimediaParameters ok OK Notifier newVersionAvailable È disponibile una nuova versione (%1)! newFileMessage Nuovo allegato ricevuto! OnlineInstallerDialog confirm CONFERMA onlineInstallerExtractingDescription Estrazione di %1... onlineInstallerDownloadingDescription Download %1... onlineInstallerFinishedDescription %1 è ora installato! onlineInstallerFailedDescription Impossibile installare %1! OutgoingMessage messageError Errore messageRead Leggi messageDelivered Consegnato Presence presenceOnline Disponibile presenceBusy Occupato presenceDoNotDisturb Non disturbare presenceOffline Offline SettingsAdvanced logsTitle Logs logsFolderLabel Cartella dei log sendLogs MANDA I LOG logsUploadUrlLabel URL del server per l'upload dei log logsUploadFailed Impossibile caricare i log. logsEnabledLabel Abilita i log cleanLogs CANCELLA I LOG cleanLogsDescription Sei sicuro di voler rimuovere tutti i log? developerSettingsTitle Impostazioni per sviluppatori developerSettingsEnabledLabel Abilita impostazioni per sviluppatori logsMailerFailed Message when Linphone try to open a mailer to send logs, after uploading them to the server (%1 would be the upload url) Impossibile trovare il mailer ma i log sono stati caricati su %1 logsMailerSuccess I log sono stati caricati a %1 SettingsAudio audioTitle Parametri Audio playbackDeviceLabel Dispositivo di riproduzione captureDeviceLabel Dispositivo di acquisizione ringerDeviceLabel Dispositivo per la suoneria ringLabel Squilla echoCancellationLabel Abilita l'eliminazione dell'eco audioCodecsTitle Codec Audio showAudioCodecsLabel Mostra i codec audio playbackGainLabel Guadagno di riproduzione captureGainLabel Acquisizione guadagno audioTestLabel Livello di acquisizione audioSettingsInCallWarning Chiamata audio in corso: alcune impostazioni non sono disponibili. SettingsCallsChat fileServerLabel File server encryptWithLimeLabel Cifrato con LIME limeDisabled Disabilitato limeRequired Obbligatorio limePreferred Preferito chatTitle Chat callsTitle Chiamate encryptionLabel Cifratura noEncryption Nessuno autoAnswerLabel Risposta automatica autoAnswerDelayLabel Ritardo (in ms) autoAnswerWithVideoLabel Risposta automatica (con video) chatEnabledLabel Abilita chat callRecorderEnabledLabel Abilita registrazione chiamata chatNotificationSoundEnabledLabel Abilita il suono di notifica chatNotificationSoundLabel Suono di notifica conferenceEnabledLabel Abilita conferenza contactsTitle Contatti contactsEnabledLabel Abilita i contatti muteMicrophoneEnabledLabel Abilita microfono muto outgoingCallsEnabledLabel Abilita chiamate in uscita showTelKeypadAutomaticallyLabel Mostra automaticamente la tastiera del telefono automaticallyRecordCallsLabel Registra automaticamente le chiamate keepCallsWindowInBackgroundLabel Mantieni la finestra chiamate in background callPauseEnabledLabel Chiamata in pausa abilitata encryptionMandatoryLabel La crittografia è obbligatoria SettingsNetwork sendDtmfsLabel Metodo di invio DTMF allowIpV6Label Abilita IPv6 transportTitle Trasporto natAndFirewallTitle NAT e Firewall enableIceLabel Abilita ICE stunServerLabel Server STUN/TURN enableTurnLabel Abilita TURN turnUserLabel Utente TURN turnPasswordLabel Password TURN networkProtocolAndPortsTitle Protocollo di rete e porte sipUdpPortLabel Porta UDP SIP sipTcpPortLabel Porta TCP SIP audioRtpUdpPortLabel Porta UDP audio RTP videoRtpUdpPortLabel Porta UDP video RTP dscpFieldsTitle Campi DSCP sipFieldLabel SIP audioRtpStreamFieldLabel Stream RTP audio videoRtpStreamFieldLabel Stream RTP video bandwidthControlTitle Controllo della larghezza di banda downloadSpeedLimitLabel Limite di velocità di download in Kbit/sec uploadSpeedLimitLabel Limite di velocità di upload in Kbit/sec enableAdaptiveRateControlLabel Abilita controllo adattivo della velocità presenceTitle Presenza rlsUriLabel Usa URI RLS rlsUriAuto AUTO rlsUriDisabled MAI showNetworkSettingsLabel Mostra le impostazioni di rete generalTitle Generale SettingsSipAccounts defaultIdentityTitle Identità predefinita defaultUsernameLabel Nome utente defaultSipAddressLabel Indirizzo SIP proxyAccountsTitle Account proxy eraseAllPasswords CANCELLA LE PASSWORD addAccount AGGIUNGI ACCOUNT editHeader Modifica deleteHeader Cancella deleteAccountDescription Sei sicuro di voler eliminare questo account? eraseAllPasswordsDescription Sei sicuro di voler cancellare tutte le password? defaultDisplayNameLabel Nome da visualizzare assistantTitle Assistente createAppSipAccountEnabledLabel Abilita la creazione dell'account useAppSipAccountEnabledLabel Abilita l'utilizzo dell'account useOtherSipAccountEnabledLabel Abilita l'utilizzo dell'account generico fetchRemoteConfigurationEnabledLabel Abilita il recupero della configurazione assistantSupportsPhoneNumbersLabel Supporta i numeri di telefono SettingsSipAccountsEdit sipAddressLabel Indirizzo SIP transportLabel Trasporto serverAddressLabel Indirizzo del server SIP registrationDurationLabel Durata della registrazione (sec) routeLabel Instradamento contactParamsLabel Parametri di contatto publishPresenceLabel Pubblica informazioni sulla presenza avpfIntervalLabel Intervallo regolare RTCP di AVPF (sec) registerEnabledLabel Registra avpfEnabledLabel Abilita AVPF cancel ANNULLA confirm CONFERMA invalidSipAddress Indirizzo SIP non valido invalidServerAddress Indirizzo del server non valido invalidRoute Instradamento non valido enableIceLabel Abilita ICE stunServerLabel Server STUN/TURN enableTurnLabel Abilita TURN turnUserLabel Utente TURN turnPasswordLabel Password TURN natAndFirewallTitle NAT e Firewall mainSipAccountSettingsTitle Impostazioni dell'account SIP principale SettingsUi pathsTitle Percorsi savedScreenshotsLabel Cartella per gli screenshot salvati savedCallsLabel Cartella per le chiamate salvate languagesTitle Lingue languagesLabel Lingua systemLocale Impostazioni locali del sistema cleanAvatars CANCELLA AVATAR cleanAvatarsDescription Sei sicuro di voler cancellare tutti gli avatar? downloadLabel Cartella per i download setLocaleDescription È necessario riavviare l'applicazione. Vuoi riavviare ora? otherTitle Altro exitOnCloseLabel Esci dall'app alla chiusura della finestra dataTitle Dati UI autoStartLabel Autoavvio dell'app SettingsVideo videoInputDeviceLabel Dispositivo di input video videoFramerateLabel Framerate videoCaptureTitle Parametri di acquisizione video videoPresetLabel Preimpostazioni video presetDefault Predefinito presetHighFps FPS elevati presetCustom Personalizzato videoSizeLabel Risoluzione Video videoCodecsTitle Codec Video showCameraPreview ANTEPRIMA VIDEO showVideoCodecsLabel Mostra codec video videoSettingsInCallWarning Videochiamata in corso: alcune impostazioni non sono disponibili. SettingsVideoPreview confirm OK SettingsWindow settingsTitle Impostazioni sipAccountsTab Account SIP audioTab Audio videoTab Video callsAndChatTab Chiamate e Chat networkTab Rete uiTab Interfaccia utente validButton OK uiAdvanced Avanzate SmartSearchBar addContact AGGIUNGI UN CONTATTO Timeline timelineTitle In precedenza UseAppSipAccount confirmAction USA useAppSipAccountTitle USA UN ACCOUNT %1 useUsernameToLogin Usa nome utente e password anziché il tuo numero di telefono. quitWarning Your account has been created but has not been validated yet. Are you sure you want to quit this view? UseAppSipAccountWithPhoneNumber countryLabel Paese phoneNumberLabel Numero di telefono UseAppSipAccountWithUsername usernameLabel Nome utente passwordLabel Password UseOtherSipAccount confirmAction USA useOtherSipAccountTitle USA UN ACCOUNT SIP usernameLabel Nome utente displayNameLabel Nome visualizzato (facoltativo) sipDomainLabel Dominio SIP passwordLabel Password transportLabel Trasporto addOtherSipAccountError Impossibile aggiungere questo account. ZrtpTokenAuthentication confirmSas Confermare il seguente SAS con la controparte. codeA Di: codeB Il tuo contatto dovrebbe dire: deny RIFIUTA accept CONFERMA country Afghanistan Afghanistan Albania Albania Algeria Algeria AmericanSamoa Samoa Americane Andorra Andorra Angola Angola Anguilla Anguilla AntiguaAndBarbuda Antigua e Barbuda Argentina Argentina Armenia Armenia Aruba Aruba Australia Australia Austria Austria Azerbaijan Azerbaigian Bahamas Bahamas Bahrain Bahrein Bangladesh Bangladesh Barbados Barbados Belarus Bielorussia Belgium Belgio Belize Belize Benin Benin Bermuda Bermuda Bhutan Bhutan Bolivia Bolivia BosniaAndHerzegowina Bosnia ed Erzegovina Botswana Botswana Brazil Brasile Brunei Brunei Bulgaria Bulgaria BurkinaFaso Burkina Faso Burundi Burundi Cambodia Cambogia Cameroon Camerun Canada Canada CapeVerde Capo Verde CaymanIslands Isole Cayman CentralAfricanRepublic Repubblica Centrafricana Chad Ciad Chile Cile China Cina Colombia Colombia Comoros Comore PeoplesRepublicOfCongo Repubblica Popolare del Congo DemocraticRepublicOfCongo Repubblica Democratica del Congo CookIslands Isole Cook CostaRica Costa Rica IvoryCoast Costa d'Avorio Croatia Croazia Cuba Cuba Cyprus Cipro CzechRepublic Repubblica Ceca Denmark Danimarca Djibouti Gibuti Dominica Dominica DominicanRepublic Repubblica Dominicana Ecuador Ecuador Egypt Egitto ElSalvador El Salvador EquatorialGuinea Guinea Equatoriale Eritrea Eritrea Estonia Estonia Ethiopia Etiopia FalklandIslands Isole Falkland FaroeIslands Isole Faroe Fiji Figi Finland Finlandia France Francia FrenchGuiana Guyana Francese FrenchPolynesia Polinesia Francese Gabon Gabon Gambia Gambia Georgia Georgia Germany Germania Ghana Ghana Gibraltar Gibilterra Greece Grecia Greenland Groenlandia Grenada Grenada Guadeloupe Guadalupa Guam Guam Guatemala Guatemala Guinea Guinea GuineaBissau Guinea-Bissau Guyana Guyana Haiti Haiti Honduras Honduras HongKong Hong Kong Hungary Ungheria Iceland Islanda India India Indonesia Indonesia Iran Iran Iraq Iraq Ireland Irlanda Israel Israele Italy Italia Jamaica Jamaica Japan Giappone Jordan Giordania Kazakhstan Kazakistan Kenya Kenya Kiribati Kiribati DemocraticRepublicOfKorea Corea del Nord RepublicOfKorea Corea del Sud Kuwait Kuwait Kyrgyzstan Kyrgyzstan Laos Laos Latvia Lettonia Lebanon Libano Lesotho Lesotho Liberia Liberia Libya Libia Liechtenstein Liechtenstein Lithuania Lituania Luxembourg Lussemburgo Macau Macao Macedonia Macedonia Madagascar Madagascar Malawi Malawi Malaysia Malaysia Maldives Maldive Mali Mali Malta Malta MarshallIslands Isole Marshall Martinique Martinica Mauritania Mauritania Mauritius Mauritius Mayotte Mayotte Mexico Messico Micronesia Micronesia Moldova Moldavia Monaco Monaco Mongolia Mongolia Montenegro Montenegro Montserrat Montserrat Morocco Marocco Mozambique Mozambico Myanmar Birmania Namibia Namibia NauruCountry Nauru Nepal Nepal Netherlands Paesi Bassi NewCaledonia Nuova Caledonia NewZealand Nuova Zelanda Nicaragua Nicaragua Niger Niger Nigeria Nigeria Niue Niue NorfolkIsland Isola Norfolk NorthernMarianaIslands Isole Marianne Settentrionali Norway Norvegia Oman Oman Pakistan Pakistan Palau Palau PalestinianTerritories Territori Palestinesi Panama Panama PapuaNewGuinea Papua Nuova Guinea Paraguay Paraguay Peru Perù Philippines Filippine Poland Polonia Portugal Portogallo PuertoRico Porto Rico Qatar Qatar Reunion Riunione Romania Romania RussianFederation Russia Rwanda Ruanda SaintHelena Sant'Elena SaintKittsAndNevis Saint Kitts e Nevis SaintLucia Saint Lucia SaintPierreAndMiquelon Saint-Pierre e Miquelon SaintVincentAndTheGrenadines Saint Vincent e Grenadine Samoa Samoa SanMarino San Marino SaoTomeAndPrincipe São Tomé e Príncipe SaudiArabia Arabia Saudita Senegal Senegal Serbia Serbia Seychelles Seychelles SierraLeone Sierra Leone Singapore Singapore Slovakia Slovacchia Slovenia Slovenia SolomonIslands Isole Salomone Somalia Somalia SouthAfrica Sudafrica Spain Spagna SriLanka Sri Lanka Sudan Sudan Suriname Suriname Swaziland Swaziland Sweden Svezia Switzerland Svizzera Syria Siria Taiwan Taiwan Tajikistan Tagikistan Tanzania Tanzania Thailand Thailandia Togo Togo Tokelau Tokelau Tonga Tonga TrinidadAndTobago Trinidad e Tobago Tunisia Tunisia Turkey Turchia Turkmenistan Turkmenistan TurksAndCaicosIslands Turks e Caicos Tuvalu Tuvalu Uganda Uganda Ukraine Ucraina UnitedArabEmirates Emirati Arabi Uniti UnitedKingdom Regno Unito UnitedStates Stati Uniti d'America Uruguay Uruguay Uzbekistan Uzbekistan Vanuatu Vanuatu Venezuela Venezuela Vietnam Vietnam WallisAndFutunaIslands Wallis e Futuna Yemen Yemen Zambia Zambia Zimbabwe Zimbabwe linphone-utils downloadCodecDescription Vuoi scaricare %1 (%2)? linphone-desktop-4.2.5/linphone-app/assets/languages/ja.ts000066400000000000000000002535661376717241300236450ustar00rootroot00000000000000 About ok OK ActivateAppSipAccountWithEmail activateAppSipAccount %1アカウントを有効にする confirmAction アクティブにします activationSteps アカウントを有効化するには:%1 に送信された指示に従い、下をクリックしてください。 ActivateAppSipAccountWithPhoneNumber activateAppSipAccount %1アカウントを有効にする confirmAction アクティブにします activationSteps 検証コードを含む SMS が %1 に送信されました。 電話番号の確認を完了するには、以下の 4 桁のコードを入力してください。 App commandLineOptionVerbose 実行中にデバッグ情報を標準出力へ出力する commandLineOptionConfig 使用する %1 構成ファイルを指定 applicationDescription 無料(自由な)SIPビデオ電話。 commandLineOptionIconified システムトレイで起動し、メインインターフェイスを表示しない commandLineOptionConfigArg ファイル commandLineOptionHelp ヘルプを表示する commandLineOptionVersion アプリケーションバージョンを表示する commandLineOptionCliHelp CLI で %1 を使用するためのヘルプメニューを表示します。 commandLineDescription コマンドラインに向かってアプリケーションに注文を送る restore [復元] quit 終了 settings 設定 about バージョン情報 AssistantAbstractView back 戻る AssistantHome useAppSipAccount %1アカウントを使用する useOtherSipAccount SIPアカウントを使用する fetchRemoteConfiguration リモート設定を取得する homeTitle ようこそ homeDescription このアシスタントはあなたの%1アカウントの設定を助けます。 createAppSipAccount %1アカウントを作成する AssistantModel loginWithUsernameFailed ログインに失敗しました。ユーザ名・パスワードを確認してください。 usernameStatusTooShort 短すぎます(最低 %1文字) usernameStatusTooLong 長すぎます(最大 %1文字) usernameStatusInvalidCharacters 無効な文字が検出されました。(正規表現: `%1`) usernameStatusInvalid 無効なユーザ名 passwordStatusTooShort 短すぎます(最低 %1文字) passwordStatusTooLong 長すぎます(最大 %1文字) passwordStatusInvalidCharacters 無効な文字が検出されました。(正規表現: `%1`) passwordStatusMissingCharacters 誤った文字: `%1` requestFailed リクエストを送信できませんでした。 emailStatusMalformed メールアドレスが間違っています。 emailStatusMalformedInvalidCharacters メールアドレスが間違っているか、無効な文字があります。 cannotSendSms サーバエラー: SMSを送信できませんでした。 accountAlreadyExists このアカウントはすでに存在します。 smsActivationFailed SMS認証に失敗しました。 emailActivationFailed アカウントを確認したことを確認するか、もう一度お試しください。 phoneNumberStatusInvalid 無効な電話番号 phoneNumberStatusTooShort 短すぎます phoneNumberStatusTooLong 長すぎます phoneNumberStatusInvalidCountryCode 無効な国番号 loginWithPhoneNumberFailed ログインに失敗しました。電話番号を確認して下さい。 unableToAddAccount このアカウントを追加出来ませんでした。 AuthenticationRequest cancel キャンセル confirm ログイン identityLabel アイデンティティ passwordLabel パスワード authenticationRequestDescription 認証に失敗しました。パスワードを確認してください。 userIdLabel ユーザID(オプション) realmLabel レルム CallModel callStatsCodec コーデック callStatsUploadBandwidth 上り帯域 callStatsDownloadBandwidth 下り帯域 callStatsEstimatedDownloadBandwidth 推定ダウンロード帯域幅 callStatsIceState ICE状態 callStatsIpFamily 知的財産 callStatsSenderLossRate 送信ロスレート callStatsReceiverLossRate 受信ロスレート callStatsJitterBuffer Jitter buffer callStatsSentVideoDefinition 送信済みビデオの定義 callStatsReceivedVideoDefinition 受信したビデオの定義 iceStateNotActivated 有効ではありません iceStateFailed 失敗 iceStateInProgress 処理中 iceStateReflexiveConnection リフレクシブ結合 iceStateHostConnection ホスト接続 iceStateRelayConnection リレー接続 iceStateInvalid 無効 callErrorDeclined 相手に拒否されました。 callErrorNotFound 相手が存在しません。 callErrorBusy 相手が話し中です。 callErrorNotAcceptable 相手が通話を受け入れることが出来ません。 callStatsReceivedFramerate 受信フレームレート callStatsSentFramerate 送信フレームレート CallSipAddress cancel キャンセル callSipAddressDescription 新しい通話を始める CallStatistics audioStatsLabel 音声 videoStatsLabel 映像 CallTransfer cancel キャンセル callTransferDescription この通話を転送しますか? Calls acceptAudioCall 音声通話を受け入れる acceptVideoCall ビデオ通話を受け入れる terminateCall 電話を切る resumeCall 電話を再開する transferCall 電話を転送する callPause 電話を保留する CallsWindow callsTitle 通話 acceptClosingDescription 全ての通話を終了してもよろしいですか? Chat newMessagePlaceholder メッセージを入力してください。 noFileTransferUrl ファイルを送信できませんでした。 サーバURLが設定されていません。 isComposing 入力中: %1 Cli appCliDescription コマンドラインから %1 アプリケーションを制御する方法。 uriCommandLineSyntax %1 <sip-address>?method=<方法>([&<argument>=<base64-value>]*) cliCommandLineSyntax %1 "<method> ([<argument>=<value>]*)" commandsName コマンドリスト: showFunctionDescription アプリケーションのメイン画面を表示する callFunctionDescription SIPアドレスへの呼び出しを開始します。 initiateConferenceFunctionDescription 会議を開始する joinConferenceFunctionDescription 表示名として、sip-address が主催する会議に参加します。 プロキシ設定に接続している場合は、「参加会議」を参照してください。 joinConferenceAsFunctionDescription ゲスト-sip-address と同様に、sip-address が主催する会議に参加します。 プロキシ設定に接続していない場合は、「参加会議」を参照してください。 CodecsViewer codecMime 名前 codecEncoderDescription 説明 codecEncoderClockRate レート (Hz) codecBitrate ビットレート (Kbit/s) codecRecvFmtp パラメータ codecStatus 状態 Conference conferenceTitle 会議 ConferenceControls conference 会議 ConferenceManager conferenceManagerDescription 会議の参加者を管理します。 cancel キャンセル confirm 開始 ConfirmDialog cancel キャンセル confirm 確認 ContactEdit removeContactDescription あなたのアドレス帳からこの連絡先を削除してもよろしいですか? sipAccounts SIPアカウント address アドレス emails メールアドレス webSites Webサイト avatarChooserTitle アバターを選択してください。 companies 企業 save 保存 cancel キャンセル sipAccountsPlaceholder SIPアカウント companiesPlaceholder 会社 emailsPlaceholder メールアドレス webSitesPlaceholder Webサイト street 通り postalCode 郵便番号 country locality 局所性 abortEditDescriptionText 連絡先の変更をキャンセルしてもよろしいですか? tooltipShowConversation 会話を表示 Contacts searchContactPlaceholder 連絡先を検索 selectAllContacts 全て selectConnectedContacts 接続済 addContact 連絡先に追加 removeContactDescription あなたのアドレス帳からこの連絡先を削除してもよろしいですか? Conversation displayCallsAndMessages 全て displayCalls を呼び出します displayMessages メッセージ removeAllEntriesDescription 履歴をクリアしてよろしいですか? tooltipContactEdit 連絡先の編集 tooltipContactAdd 連絡先の追加 cleanHistory 履歴の削除 CreateAppSipAccount createAppSipAccountDescription どのようにアカウントを作成しますか? createAppSipAccountTitle %1アカウントを作成する withPhoneNumber 電話番号を利用 withEmailAddress メールアドレスを利用 CreateAppSipAccountWithEmail createAppSipAccountTitle %1アカウントを作成 confirmAction 作成 usernameLabel ユーザ名 emailLabel メールアドレス passwordLabel パスワード passwordConfirmationLabel パスワード(確認) passwordConfirmationError 入力されたパスワードが一致しません。 quitWarning アカウントは作成されましたが、まだ確認されていません。この画面を終了してもよろしいですか? displayNameLabel 表示名(オプション) CreateAppSipAccountWithPhoneNumber createAppSipAccountTitle %1アカウントを作成する countryLabel phoneNumberLabel 電話番号 usernameLabel ユーザ名 displayNameLabel 表示名(オプション) confirmAction 作成 quitWarning アカウントは作成されましたが、まだ確認が完了していません。このビューを終了するには、24時間以内に手動でアカウントを追加して検証する必要があります。 DroppableTextArea fileChooserTitle 1 つまたは複数のファイルを選択してください dropYourAttachment 添付ファイルをドロップする attachmentTooltip ファイルを送信 Event incomingCall 着信 outgoingCall 発信 declinedIncomingCall 拒否された着信通話 declinedOutgoingCall 拒否された発信通話 endedCall 通話終了 missedIncomingCall 不在着信 missedOutgoingCall 不在の発信 FetchRemoteConfiguration confirmAction フェッチ fetchRemoteConfigurationTitle リモート設定の取得 urlLabel URL remoteProvisioningError リモートプロビジョニングファイルがセット出来ませんでした。 remoteProvisioningUpdateDescription アプリケーションを再起動する必要があります。今すぐ再起動しますか? HistoryView removeAllEntriesDescription 履歴をクリアしてよろしいですか? tooltipContactEdit 連絡先の編集 tooltipContactAdd 連絡先の追加 cleanHistory 履歴の削除 Home howToDescription %1の使い方にヘルプが必要ですか? howToTitle %1 の使用方法 inviteDescription あなたの友達に%1を紹介 inviteTitle あなたの友人を招待する accountAssistantDescription %1アカウントを作成/管理する accountAssistantTitle アカウントアシスタント assistantButton アシスタント showTooltips ツールチップを表示 inviteButton 招待 Incall acceptVideoDescription あなたの連絡先がビデオをオンにしました。 pendingRequestLabel リクエストを処理しています。しばらくお待ちください。 securedStringFormat 通話は %1 で暗号化されています。 callNotSecured 通話は暗号化されていません。 takeSnapshotLabel スナップショットを撮る startRecordingLabel 録音開始 stopRecordingLabel 録音停止 IncallFullscreenWindow takeSnapshotLabel スナップショットを撮る startRecordingLabel 録音開始 stopRecordingLabel 録音停止 InviteFriends enterEmailLabel 友達のメールアドレス messageLabel メッセージ cancel キャンセル confirm 確認 inviteFriendsTitle 友達を招待 defaultMessage %1 があなたを%2に招待しています。 defaultSubject %1への招待 forcedMessage お使いのコンピュータにアプリケーションをダウンロードして、通話を開始し、無料でユーザーとチャットします。 ここをクリック:<a href="%1">%1</a> MainWindow mainSearchBarPlaceholder 連絡先を検索するか、通話もしくはチャットを始める homeEntry ホーム contactsEntry 連絡先 autoAnswerStatus 自動 smartSearchBarTooltip インテリジェントな検索バーを使用してオーディオとビデオを直接開始 を呼び出したり、メッセージを送信したり、新しい連絡先を追加したりできます。 入力するだけです あなたの友人のSIPアドレスまたはユーザー名。 newConferenceButton 電話会議の開始 MainWindowMenuBar settings 設定 about バージョン情報 quit 終了 MainWindowTopMenuBar settings 環境設定 about バージョン情報 quit やめろ ManageAccounts ok OK selectPresenceLabel プレゼンス状態 selectAccountLabel 有効なアカウント Message menuCopy -了解 menuPlayMe 俺をプレイしろ! MultimediaParameters ok OK Notifier newVersionAvailable 新しいバージョン (%1) が利用可能です! newFileMessage 新しい添付ファイルが届きました! OnlineInstallerDialog confirm 確認する onlineInstallerExtractingDescription %1 を抽出しています... onlineInstallerDownloadingDescription %1 をダウンロードしています... onlineInstallerFinishedDescription %1 がインストールされました! onlineInstallerFailedDescription %1 のインストールに失敗しました! OutgoingMessage messageError エラー messageRead 読む messageDelivered 配信済 Presence presenceOnline 利用可能 presenceBusy 話中 presenceDoNotDisturb 不在 presenceOffline オフライン SettingsAdvanced logsTitle ログ logsFolderLabel ログフォルダー sendLogs ログを送信 logsUploadUrlLabel ログのアップロード先URL logsUploadFailed ログのアップロードに失敗しました logsEnabledLabel ログ 有効 cleanLogs ログを削除する cleanLogsDescription 全てのログを削除してもよろしいですか? developerSettingsTitle 開発者設定 developerSettingsEnabledLabel 開発者設定を有効にする logsMailerFailed Message when Linphone try to open a mailer to send logs, after uploading them to the server (%1 would be the upload url) メーラは見つかりませんが、ログが %1 にアップロードされました logsMailerSuccess ログが %1 にアップロードされました SettingsAudio audioTitle オーディオ設定 playbackDeviceLabel 再生デバイス captureDeviceLabel キャプチャーデバイス ringerDeviceLabel 着信音デバイス ringLabel 着信音 echoCancellationLabel エコーキャンセラ-を有効にする audioCodecsTitle オーディオコーデック showAudioCodecsLabel オーディオコーデックを表示する playbackGainLabel 再生ゲイン captureGainLabel キャプチャーゲイン audioTestLabel キャプチャ・レベル audioSettingsInCallWarning 音声通話中:一部の設定が使用できません。 SettingsCallsChat fileServerLabel ファイルサーバ encryptWithLimeLabel LIME で暗号化 limeDisabled 無効 limeRequired 必須 limePreferred 優先 chatTitle チャット callsTitle 通話 encryptionLabel 暗号化 noEncryption 無し autoAnswerLabel 自動応答 autoAnswerDelayLabel 応答までの時間(ミリ秒) autoAnswerWithVideoLabel 自動応答(映像) chatEnabledLabel チャットを有効にする callRecorderEnabledLabel コールレコーダを有効にする chatNotificationSoundEnabledLabel 通知音を有効にする chatNotificationSoundLabel 通知音 conferenceEnabledLabel 会議を有効にする contactsTitle 連絡先 contactsEnabledLabel 連絡先の有効化 muteMicrophoneEnabledLabel マイクのミュートを有効にする outgoingCallsEnabledLabel 発信コールを有効にする showTelKeypadAutomaticallyLabel 電話のキーパッドを自動的に表示する automaticallyRecordCallsLabel 通話を自動的に録音する keepCallsWindowInBackgroundLabel 通話ウィンドウをバックグラウンドに保持 callPauseEnabledLabel 保留コールの有効化 encryptionMandatoryLabel 凍結は必須です SettingsNetwork sendDtmfsLabel DTMF送信方法 allowIpV6Label IPv6を有効にする transportTitle トランスポート natAndFirewallTitle NAT and Firewall enableIceLabel ICEを有効にする stunServerLabel STUN/TURN server enableTurnLabel TURNを有効にする turnUserLabel TURNユーザ turnPasswordLabel TURNパスワード networkProtocolAndPortsTitle ネットワークプロトコルとポート sipUdpPortLabel SIP UDPポート sipTcpPortLabel SIP TCPポート audioRtpUdpPortLabel オーディオRTP UDPポート videoRtpUdpPortLabel ビデオRTP UDPポート dscpFieldsTitle DSCPフィールド sipFieldLabel SIP audioRtpStreamFieldLabel 音声RTPストリーム videoRtpStreamFieldLabel ビデオRTPストリーム bandwidthControlTitle 帯域制御 downloadSpeedLimitLabel ダウンロード速度制限 Kbit/sec uploadSpeedLimitLabel アップロード速度制限 Kbit/sec enableAdaptiveRateControlLabel 適応型レート制御を有効にする presenceTitle プレゼンス rlsUriLabel RLS URIを使う rlsUriAuto 自動 rlsUriDisabled 決して showNetworkSettingsLabel ネットワーク設定を表示する generalTitle 将軍 SettingsSipAccounts defaultIdentityTitle デフォルトのアイデンティティ defaultUsernameLabel ユーザ名 defaultSipAddressLabel SIPアドレス proxyAccountsTitle Proxyアカウント eraseAllPasswords パスワード消去 addAccount アカウントの追加 editHeader 編集 deleteHeader 削除 deleteAccountDescription あなたのアカウントを削除してもよろしいですか? eraseAllPasswordsDescription あなたのパスワードを消してもよろしいですか? defaultDisplayNameLabel 表示名 assistantTitle アシスタント createAppSipAccountEnabledLabel アカウント作成を有効にする useAppSipAccountEnabledLabel アカウントの使用を有効にする useOtherSipAccountEnabledLabel 一般的なアカウントの使用を有効にする fetchRemoteConfigurationEnabledLabel 構成フェッチの有効化 assistantSupportsPhoneNumbersLabel 電話番号をサポート SettingsSipAccountsEdit sipAddressLabel SIPアドレス transportLabel トランスポート serverAddressLabel SIPサーバ アドレス registrationDurationLabel 登録間隔(秒) routeLabel ルート contactParamsLabel Contactパラメータ publishPresenceLabel プレゼンス情報を公開する avpfIntervalLabel AVPF 通常のRTCP間隔(秒) registerEnabledLabel 登録 avpfEnabledLabel AVPFを有効にする cancel キャンセル confirm 確認 invalidSipAddress 無効なSIPアドレス invalidServerAddress 無効なサーバアドレスです。 invalidRoute 無効なルート enableIceLabel ICE を有効にする stunServerLabel STUN/URNサーバ enableTurnLabel TURNを有効にする turnUserLabel TURNユーザー turnPasswordLabel TURNパスワード natAndFirewallTitle NAT とファイアウォール mainSipAccountSettingsTitle メイン SIP アカウント設定 SettingsUi pathsTitle パス savedScreenshotsLabel スクリーンショットの保存先フォルダ savedCallsLabel 保存済み通話フォルダ languagesTitle 言語 languagesLabel 言語 systemLocale システム・ロケール cleanAvatars アバターを削除 cleanAvatarsDescription あなたのアバターを削除してもよろしいですか? downloadLabel ダウンロードフォルダー setLocaleDescription アプリケーションを再起動する必要があります。今すぐ再起動しますか? otherTitle その他 exitOnCloseLabel ウィンドウを閉じるとアプリケーションを終了する dataTitle UI データ autoStartLabel アプリの自動起動 SettingsVideo videoInputDeviceLabel ビデオ入力デバイス videoFramerateLabel フレームレート videoCaptureTitle ビデオキャプチャー設定 videoPresetLabel ビデオプリセット presetDefault 標準 presetHighFps 高FPS presetCustom カスタム videoSizeLabel 映像解像度 videoCodecsTitle ビデオコーデック showCameraPreview ビデオプレビュー showVideoCodecsLabel ビデオコーデックを表示する videoSettingsInCallWarning ビデオ通話中:一部の設定が使用できません。 SettingsVideoPreview confirm OK SettingsWindow settingsTitle 設定 sipAccountsTab SIPアカウント audioTab 音声 videoTab 映像 callsAndChatTab 通話及びチャット networkTab ネットワーク uiTab ユーザインターフェース validButton OK uiAdvanced 詳細 SmartSearchBar addContact 連絡先に追加 Timeline timelineTitle 以前 UseAppSipAccount confirmAction 使う useAppSipAccountTitle %1アカウントを使用する useUsernameToLogin 電話番号ではなく、ユーザー名とパスワードを使用します。 quitWarning アカウントは作成されましたが、まだ確認されていません。この画面を終了してもよろしいですか? UseAppSipAccountWithPhoneNumber countryLabel phoneNumberLabel 電話番号 UseAppSipAccountWithUsername usernameLabel ユーザ名 passwordLabel パスワード UseOtherSipAccount confirmAction 使う useOtherSipAccountTitle SIPアカウントを使う usernameLabel ユーザ名 displayNameLabel 表示名(オプション) sipDomainLabel SIPドメイン passwordLabel パスワード transportLabel トランスポート addOtherSipAccountError このアカウントを追加出来ませんでした。 ZrtpTokenAuthentication confirmSas ピアと次のSASを確認します。 codeA 次のように入力します。 codeB 連絡先の内容は次のとおりです。 deny 拒否 accept 確認 country Afghanistan アフガニスタン Albania アルバニア Algeria アルジェリア AmericanSamoa アメリカ領サモア Andorra アンドラ Angola アンゴラ Anguilla アンギラ AntiguaAndBarbuda アンティグア・バーブーダ Argentina アルゼンチン Armenia アルメニア Aruba アルバ Australia オーストラリア Austria オーストリア Azerbaijan アゼルバイジャン Bahamas バハマ Bahrain バーレーン Bangladesh バングラデシュ Barbados バルバドス Belarus ベラルーシ Belgium ベルギー Belize ベリーズ Benin ベナン Bermuda バミューダだ Bhutan ブータン Bolivia ボリビア BosniaAndHerzegowina ボスニア・ヘルツェゴビナ Botswana ボツワナ Brazil ブラジル Brunei ブルネイ Bulgaria ブルガリア BurkinaFaso ブルキナファソ Burundi ブルンジ Cambodia カンボジア Cameroon カメルーン Canada カナダ CapeVerde カーボベルデ CaymanIslands ケイマン諸島 CentralAfricanRepublic 中央アフリカ共和国 Chad チャド Chile チリ China 中国 Colombia コロンビア Comoros コモロ PeoplesRepublicOfCongo コンゴ共和国 DemocraticRepublicOfCongo コンゴ民主共和国 CookIslands クック諸島 CostaRica コスタリカ IvoryCoast コートジボワール Croatia クロアチア Cuba キューバ Cyprus キプロス CzechRepublic チェコ共和国 Denmark デンマーク Djibouti ジブチ Dominica ドミニカか DominicanRepublic ドミニカ共和国 Ecuador エクアドル Egypt エジプト ElSalvador エルサルバドル EquatorialGuinea 赤道ギニア Eritrea エリトリア Estonia エストニア Ethiopia エチオピア FalklandIslands フォークランド諸島 FaroeIslands フェロー諸島 Fiji フィジー Finland フィンランド France フランス FrenchGuiana フランス領ギアナ FrenchPolynesia フランス領ポリネシア Gabon ガボン Gambia ガンビア Georgia ジョージア Germany ドイツ Ghana ガーナ Gibraltar ジブラルタル Greece ギリシャ Greenland グリーンランド Grenada グレナダ Guadeloupe グアドループ Guam グアム Guatemala グアテマラ Guinea ギニア GuineaBissau ギニア・ビサウ Guyana ガイアナ Haiti ハイチ Honduras ホンジュラス HongKong 香港 Hungary ハンガリー Iceland アイスランド India インド Indonesia インドネシア Iran イラン Iraq イラク Ireland アイルランド Israel イスラエル Italy イタリア Jamaica ジャマイカ Japan 日本 Jordan ジョーダン Kazakhstan カザフスタン Kenya ケニア Kiribati キリバス DemocraticRepublicOfKorea 朝鮮民主主義共和国 RepublicOfKorea 大韓民国 Kuwait クウェート Kyrgyzstan キルギス Laos ラオス Latvia ラトビア Lebanon レバノン Lesotho レソト Liberia リベリア Libya リビア Liechtenstein リヒテンシュタイン Lithuania リトアニア Luxembourg ルクセンブルク Macau マカオ Macedonia マケドニア Madagascar マダガスカル Malawi マラウイ Malaysia マレーシア Maldives モルディブ Mali マリ Malta マルタ MarshallIslands マーシャル諸島 Martinique マルティニーク Mauritania モーリタニア Mauritius モーリシャス Mayotte マヨット Mexico メキシコ Micronesia ミクロネシア Moldova モルドバ Monaco モナコ Mongolia モンゴル Montenegro モンテネグロ Montserrat モントセラト Morocco モロッコ Mozambique モザンビーク Myanmar ミャンマー Namibia ナミビア NauruCountry ナウル Nepal ネパール Netherlands オランダ NewCaledonia ニューカレドニア NewZealand ニュージーランド Nicaragua ニカラグア Niger ニジェール Nigeria ナイジェリア Niue ニウエ NorfolkIsland ノーフォーク島 NorthernMarianaIslands 北マリアナ諸島 Norway ノルウェー Oman オマーン Pakistan パキスタン Palau パラオ PalestinianTerritories パレスチナ自治区 Panama パナマ PapuaNewGuinea パプアニューギニア Paraguay パラグアイ Peru ペルー Philippines フィリピン Poland ポーランド Portugal ポルトガル PuertoRico プエルトリコ Qatar カタール Reunion 再会 Romania ルーマニア RussianFederation ロシア連邦 Rwanda ルワンダ SaintHelena セントヘレナ SaintKittsAndNevis セントクリストファー・ネイビス SaintLucia セントルシア SaintPierreAndMiquelon サンピエール島・ミクロン島 SaintVincentAndTheGrenadines セントビンセントおよびグレナディーン Samoa サモア SanMarino サンマリノ SaoTomeAndPrincipe サントメ・プリンシペ SaudiArabia サウジアラビア Senegal セネガル Serbia セルビア Seychelles セーシェル SierraLeone シエラレオネ Singapore シンガポール Slovakia スロバキア Slovenia スロベニア SolomonIslands ソロモン諸島 Somalia ソマリア SouthAfrica 南アフリカ Spain スペイン SriLanka スリランカ Sudan スーダン Suriname スリナム Swaziland スワジランド Sweden スウェーデン Switzerland スイス Syria シリア Taiwan 台湾 Tajikistan タジキスタン Tanzania タンザニア Thailand タイ Togo トーゴ Tokelau トケラウ Tonga トンガ TrinidadAndTobago トリニダード・トバゴ Tunisia チュニジア Turkey トルコ Turkmenistan トルクメニスタン TurksAndCaicosIslands タークス・カイコス諸島 Tuvalu ツバル Uganda ウガンダ Ukraine ウクライナ UnitedArabEmirates アラブ首長国連邦 UnitedKingdom イギリス UnitedStates アメリカ合衆国 Uruguay ウルグアイ Uzbekistan ウズベキスタン Vanuatu バヌアツ Venezuela ベネズエラ Vietnam ベトナム WallisAndFutunaIslands ウォリス・フトゥナ諸島 Yemen イエメン Zambia ザンビア Zimbabwe ジンバブエ linphone-utils downloadCodecDescription %1 (%2) をダウンロードしますか? linphone-desktop-4.2.5/linphone-app/assets/languages/lt.ts000066400000000000000000002430271376717241300236610ustar00rootroot00000000000000 About ok GERAI ActivateAppSipAccountWithEmail activateAppSipAccount Aktyvuokite savo %1 SĄSKAITĄ confirmAction AKTYVUOTI activationSteps Norėdami aktyvuoti savo paskyrą: sekite jums į %1 išsiųstas instrukcijas, o tuomet spustelėkite žemiau. ActivateAppSipAccountWithPhoneNumber activateAppSipAccount Aktyvuokite savo %1 SĄSKAITĄ confirmAction AKTYVUOTI activationSteps SMS žinutę su patvirtinimo kodu išsiuntėme į %1. Norėdami užbaigti savo telefono numerio patvirtinimą, žemiau įveskite 4 skaitmenų kodą. App commandLineOptionVerbose paleidus, registruoti kai kurią derinimo informaciją į stdout commandLineOptionConfig nurodyti norimą naudoti %1 konfigūracijos failą applicationDescription Nemokamas (laisvas) SIP vaizdo telefonas. commandLineOptionIconified paleisti sistemos dėkle, nerodyti pagrindinės sąsajos commandLineOptionConfigArg failas commandLineOptionHelp rodyti šią pagalbą commandLineOptionVersion rodyti programos versiją commandLineOptionCliHelp rodo pagalbos meniu, skirtą naudoti %1 su komandų eilute commandLineDescription siųsti programai įsakymą į komandų eilutę restore Atkurti quit Išeiti settings Nuostatos about Apie AssistantAbstractView back ATGAL AssistantHome useAppSipAccount NAUDOTI %1 PASKYRĄ useOtherSipAccount NAUDOTI SIP PASKYRĄ fetchRemoteConfiguration GAUTI NUOTOLINĘ KONFIGŪRACIJĄ homeTitle SVEIKI homeDescription Šis pagelbiklis padės jums sukonfigūruoti ir naudoti savo %1 paskyrą. createAppSipAccount SUSIKURTI %1 PASKYRĄ AssistantModel loginWithUsernameFailed Prisijungimas nepavyko. Patikrinkite savo naudotojo vardą/slaptažodį. usernameStatusTooShort Per trumpas! (mažiausiai %1 simb.) usernameStatusTooLong Per ilgas! (daugiausiai %1 simb.) usernameStatusInvalidCharacters Aptikti neteisingi simboliai. (reguliarusis reiškinys: "%1") usernameStatusInvalid Neteisingas naudotojo vardas. passwordStatusTooShort Per trumpas! (mažiausiai %1 simb.) passwordStatusTooLong Per ilgas! (daugiausiai %1 simb.) passwordStatusInvalidCharacters Aptikti neteisingi simboliai. (reguliarusis reiškinys: "%1") passwordStatusMissingCharacters Trūkstami simboliai: "%1". requestFailed Nepavyko išsiųsti užklausos. emailStatusMalformed Neteisingas el. pašto adresas. emailStatusMalformedInvalidCharacters Neteisingas el. pašto adresas arba neteisingi simboliai. cannotSendSms Serverio klaida: nepavyko išsiųsti sms. accountAlreadyExists Tokia paskyra jau yra. smsActivationFailed Aktyvavimas SMS žinute nepavyko! emailActivationFailed Įsitikinkite, kad esate patvirtinę savo paskyrą ir bandykite dar kartą. phoneNumberStatusInvalid Neteisingas telefono numeris! phoneNumberStatusTooShort Per trumpas! phoneNumberStatusTooLong Per ilgas! phoneNumberStatusInvalidCountryCode Neteisingas šalies kodas! loginWithPhoneNumberFailed Prisijungimas nepavyko. Patikrinkite savo telefono numerį. unableToAddAccount Nepavyko pridėti šios paskyros. AuthenticationRequest cancel ATSISAKYTI confirm PRISIJUNGTI identityLabel Tapatybė passwordLabel Slaptažodis authenticationRequestDescription Nepavyko nustatyti tapatybę. Patikrinkite savo slaptažodį. userIdLabel Naudotojo ID (nebūtina) realmLabel Karalystė CallModel callStatsCodec Kodekas callStatsUploadBandwidth Išsiuntimo sparta callStatsDownloadBandwidth Atsiuntimo sparta callStatsEstimatedDownloadBandwidth Apskaičiuotoji atsiuntimo sparta callStatsIceState ICE būsena callStatsIpFamily IP šeima callStatsSenderLossRate Siuntėjo nuostolių procentas callStatsReceiverLossRate Imtuvo nuostolių lygis callStatsJitterBuffer Jitter buferis callStatsSentVideoDefinition Išsiųsto vaizdo apibrėžimas callStatsReceivedVideoDefinition Gauto vaizdo apibrėžimas iceStateNotActivated Neaktyvuota iceStateFailed Nepavyko iceStateInProgress Eigoje iceStateReflexiveConnection Refleksinis ryšys iceStateHostConnection Pagrindinio kompiuterio ryšys iceStateRelayConnection Relės jungtis iceStateInvalid Neteisinga callErrorDeclined Nuotolinė šalis atsisakė skambučio. callErrorNotFound Nuotolinis vakarėlis nerastas. callErrorBusy Nuotolinis vakarėlis užimtas. callErrorNotAcceptable Nuotolinė šalis negali priimti skambučio. callStatsReceivedFramerate Gautas kadrų dažnis callStatsSentFramerate Išsiųstas kadrų dažnis CallSipAddress cancel ATSISAKYTI callSipAddressDescription Pradėti naują skambutį. CallStatistics audioStatsLabel Garsas videoStatsLabel Vaizdas CallTransfer cancel ATSISAKYTI callTransferDescription Ar norite perduoti šį skambutį? Calls acceptAudioCall Priimti garso skambutį acceptVideoCall Priimti vaizdo skambutį terminateCall Baigti skambutį resumeCall PRATĘSTI SKAMBUTĮ transferCall SIUNTIMAS callPause PRISTABDYTI SKAMBUTĮ CallsWindow callsTitle Skambučiai acceptClosingDescription Ar norite baigti visus skambučius? Chat newMessagePlaceholder Įrašykite savo žinutę noFileTransferUrl Nepavyko išsiųsti failą. Nesukonfigūruotas serverio url. isComposing %1 rašo... Cli appCliDescription Būdai valdyti %1 programą per komandų eilutę. uriCommandLineSyntax %1 <sip-address>?method=<metodas>([&<argument>=<base64-value>]*) cliCommandLineSyntax %1 "<method> ([<argument>=<value>]*)" commandsName komandų sąrašas : showFunctionDescription Rodyti pagrindinį programos langą. callFunctionDescription Inicijuoti skambutį į sip adresą. initiateConferenceFunctionDescription Inicijuoti konferenciją joinConferenceFunctionDescription Prisijunkite prie konferencijos, kuriai nurodytas sip adresas, rodomu vardu. Jei esate prisijungę prie tarpinio serverio konfigūracijos, žr. joinConferenceAsFunctionDescription Prisijunkite prie konferencijos, kuriai skirtas sip adresas, kaip su svečio sip adresu. Jei nesate prisijungę prie tarpinio serverio konfigūracijos, skaitykite prisijungimo konferenciją. CodecsViewer codecMime Pavadinimas codecEncoderDescription Aprašas codecEncoderClockRate Dažnis (Hz) codecBitrate Pralaidumas (Kbit/s) codecRecvFmtp Parametrai codecStatus Būsena Conference conferenceTitle KONFERENCIJA ConferenceControls conference KONFERENCIJA ConferenceManager conferenceManagerDescription Tvarkykite savo konferencijos dalyvius. cancel ATSISAKYTI confirm PRADĖTI ConfirmDialog cancel ATSISAKYTI confirm PATVIRTINTI ContactEdit removeContactDescription Ar tikrai norite pašalinti šį kontaktą iš savo adresų knygos? sipAccounts SIP PASKYRA(-OS) address ADRESAS emails EL. PAŠTAS(-AI) webSites SVETAINĖ(-S) avatarChooserTitle Pasirinkite savo avatarą companies KOMPANIJOS save ĮRAŠYTI cancel ATSISAKYTI sipAccountsPlaceholder SIP paskyra companiesPlaceholder Kompanija emailsPlaceholder El. paštas webSitesPlaceholder Svetainė street Gatvė postalCode Pašto kodas country Šalis locality Vietovė abortEditDescriptionText Ar tikrai norite atšaukti kontaktų pakeitimą? tooltipShowConversation Rodyti pokalbį Contacts searchContactPlaceholder Ieškoti kontakto selectAllContacts Visi selectConnectedContacts Prisijungę addContact PRIDĖTI KONTAKTĄ removeContactDescription Ar tikrai norite pašalinti šį kontaktą iš savo adresų knygos? Conversation displayCallsAndMessages VISKAS displayCalls SKAMBUČIAI displayMessages ŽINUTĖS removeAllEntriesDescription Ar tikrai norite išvalyti šią istoriją? tooltipContactEdit Redaguoti kontaktą tooltipContactAdd Pridėti kontaktą cleanHistory Ištrinti istoriją CreateAppSipAccount createAppSipAccountDescription Kaip norėtumėte susikurti savo paskyrą? createAppSipAccountTitle SUSIKURTI %1 PASKYRĄ withPhoneNumber NAUDOJANT TELEFONO NUMERĮ withEmailAddress NAUDOJANT EL. PAŠTO ADRESĄ CreateAppSipAccountWithEmail createAppSipAccountTitle SUSIKURTI %1 PASKYRĄ confirmAction SUKURTI usernameLabel Naudotojo vardas emailLabel El. paštas passwordLabel Slaptažodis passwordConfirmationLabel Pakartokite slaptažodį passwordConfirmationError Jūsų įvesti slaptažodžiai nesutampa. quitWarning Jūsų paskyra buvo sukurta, tačiau dar nebuvo patvirtinta. Ar tikrai norite išeiti iš šio rodinio? displayNameLabel Rodomas vardas (nebūtina) CreateAppSipAccountWithPhoneNumber createAppSipAccountTitle SUSIKURTI %1 PASKYRĄ countryLabel Šalis phoneNumberLabel Telefono numeris usernameLabel Naudotojo vardas displayNameLabel Rodomas vardas (nebūtina) confirmAction SUKURTI quitWarning Jūsų paskyra buvo sukurta, bet dar nepatvirtinta. Jei atsisakysite šio rodinio, turėtumėte rankiniu būdu pridėti ir patvirtinti savo sąskaitą per 24 valandas. DroppableTextArea fileChooserTitle Pasirinkite vieną ar daugiau failų dropYourAttachment Vilkite priedą attachmentTooltip Siųsti failą Event incomingCall Gaunamasis skambutis outgoingCall Išsiunčiamasis skambutis declinedIncomingCall Atmestas gaunamasis skambutis declinedOutgoingCall Atmestas išsiunčiamasis skambutis endedCall Nutrauktas skambutis missedIncomingCall Praleistas gaunamasis skambutis missedOutgoingCall Praleistas išsiunčiamasis skambutis FetchRemoteConfiguration confirmAction GAUTI fetchRemoteConfigurationTitle GAUTI NUOTOLINĘ KONFIGŪRACIJĄ urlLabel URL remoteProvisioningError Neįmanoma nustatyti šio nuotolinio aprūpinimo uri. remoteProvisioningUpdateDescription Yra būtina paleisti programą iš naujo. Ar norite tai atlikti dabar? HistoryView removeAllEntriesDescription Ar tikrai norite išvalyti šią istoriją? tooltipContactEdit Redaguoti kontaktą tooltipContactAdd Pridėti kontaktą cleanHistory Ištrinti istoriją Home howToDescription Reikia pagalbos kaip naudotis %1? howToTitle KAIP NAUDOTIS %1 inviteDescription Pakvieskite savo draugus į %1. inviteTitle PAKVIESTI SAVO DRAUGUS accountAssistantDescription Susikurkite ar tvarkykite savo %1 paskyrą. accountAssistantTitle PASKYRŲ PAGELBIKLIS assistantButton PAGELBIKLIS showTooltips Rodyti paaiškinimus. inviteButton PAKVIESTI Incall acceptVideoDescription Jūsų kontaktas norėtų įjungti vaizdą. pendingRequestLabel Palaukite, laukiama užklausa. securedStringFormat Skambutis yra šifruotas, naudojant: %1. callNotSecured Skambutis nėra šifruotas. takeSnapshotLabel Padarykite momentinę nuotrauką. startRecordingLabel Pradėkite įrašymą. stopRecordingLabel Nustokite įrašinėti. IncallFullscreenWindow takeSnapshotLabel Padarykite momentinę nuotrauką. startRecordingLabel Pradėkite įrašymą. stopRecordingLabel Nustokite įrašinėti. InviteFriends enterEmailLabel Draugo el. pašto adresas messageLabel Žinutė cancel ATSISAKYTI confirm PATVIRTINTI inviteFriendsTitle Pakviesti draugus defaultMessage %1 nori pakviesti jus į %2! defaultSubject %1 pakvietimas forcedMessage Atsisiųskite programą į savo kompiuterį ir skambinkite bei kalbėkitės su naudotojais nemokamai. Spustelėkite čia: <a href="%1">%1</a> MainWindow mainSearchBarPlaceholder Ieškoti kontaktų, pradėti skambutį ar pokalbį... homeEntry PRADŽIA contactsEntry KONTAKTAI autoAnswerStatus automatinis smartSearchBarTooltip Naudokite išmaniąją paieškos juostą, norėdami tiesiogiai pradėti garso ir vaizdo skambučius, siųsti žinutę ar pridėti naują kontaktą. Tiesiog, įveskite savo draugo SIP adresą ar naudotojo vardą. newConferenceButton Pradėti konferencinį pokalbį MainWindowMenuBar settings Nuostatos about Apie quit Išeiti MainWindowTopMenuBar settings Nuostatos about Apie quit Mesti ManageAccounts ok GERAI selectPresenceLabel Dalyvavimo būsena selectAccountLabel Aktyvi paskyra Message menuCopy Kopijuoti menuPlayMe Žaisk su manim! MultimediaParameters ok GERAI Notifier newVersionAvailable Yra prieinama nauja versija (%1)! newFileMessage Gautas naujas priedas! OnlineInstallerDialog confirm PATVIRTINTI onlineInstallerExtractingDescription Išskleidžiama %1... onlineInstallerDownloadingDescription Atsiunčiama %1... onlineInstallerFinishedDescription Dabar, %1 yra įdiegta! onlineInstallerFailedDescription Nepavyko įdiegti %1! OutgoingMessage messageError Klaida messageRead Perskaityta messageDelivered Pristatyta Presence presenceOnline Pasiekiamas presenceBusy Užsiėmęs presenceDoNotDisturb Netrukdyti presenceOffline Atsijungęs SettingsAdvanced logsTitle Žurnalai logsFolderLabel Žurnalų aplankas sendLogs SIŲSTI ŽURNALUS logsUploadUrlLabel Žurnalų įkėlimo serverio url logsUploadFailed Nepavyko įkelti žurnalų. logsEnabledLabel Žurnalai įjungti cleanLogs IŠVALYTI ŽURNALUS cleanLogsDescription Ar tikrai norite pašalinti visus žurnalus? developerSettingsTitle Kūrėjo nustatymai developerSettingsEnabledLabel Įjungti kūrėjo nustatymus logsMailerFailed Message when Linphone try to open a mailer to send logs, after uploading them to the server (%1 would be the upload url) Mailerio nerandama, bet žurnalai buvo įkelti į %1 logsMailerSuccess Žurnalai buvo įkelti į %1 SettingsAudio audioTitle Garso parametrai playbackDeviceLabel Atkūrimo įrenginys captureDeviceLabel Fiksavimo įrenginys ringerDeviceLabel Skambėjimo įtaisas ringLabel Žiedas echoCancellationLabel Įjungti aido malšinimą audioCodecsTitle Garso kodekai showAudioCodecsLabel Rodyti garso kodekus playbackGainLabel Atkūrimo prieaugis captureGainLabel Užfiksuokite pelną audioTestLabel Fiksavimo lygis audioSettingsInCallWarning Vyksta garso skambutis: kai kurie nustatymai negalimi. SettingsCallsChat fileServerLabel Failų serveris encryptWithLimeLabel Šifruoti naudojant LIME limeDisabled Išjungta limeRequired Privaloma limePreferred Pageidautina chatTitle Pokalbiai callsTitle Skambučiai encryptionLabel Šifravimas noEncryption Nėra autoAnswerLabel Automatiškai atsiliepti autoAnswerDelayLabel Delsa (ms) autoAnswerWithVideoLabel Automatinis atsakymas (su vaizdo įrašu) chatEnabledLabel Įgalinti pokalbį callRecorderEnabledLabel Įgalinti skambučių įrašymo įrenginį chatNotificationSoundEnabledLabel Įjungti pranešimų garsą chatNotificationSoundLabel Pranešimų garsas conferenceEnabledLabel Įgalinti konferenciją contactsTitle Kontaktai contactsEnabledLabel Įgalinti kontaktus muteMicrophoneEnabledLabel Įjungti mikrofono nutildymą outgoingCallsEnabledLabel Įgalinti išeinančius skambučius showTelKeypadAutomaticallyLabel Rodyti telefono klaviatūrą automatiškai automaticallyRecordCallsLabel Automatiškai įrašyti skambučius keepCallsWindowInBackgroundLabel Laikykite skambučių langus fone callPauseEnabledLabel Aktyvuoti pokalbį encryptionMandatoryLabel Šifravimas yra privalomas SettingsNetwork sendDtmfsLabel DTMF siuntimo būdas allowIpV6Label Leisti IPv6 transportTitle Perdavimas natAndFirewallTitle NAT ir užkarda enableIceLabel Įjungti ICE stunServerLabel STUN/TURN serveris enableTurnLabel Įjungti TURN turnUserLabel TURN naudotojas turnPasswordLabel TURN slaptažodis networkProtocolAndPortsTitle Tinklo protokolas ir prievada sipUdpPortLabel SIP UDP prievadas sipTcpPortLabel SIP TCP prievadas audioRtpUdpPortLabel Garso RTP UDP prievadas videoRtpUdpPortLabel Vaizdo RTP UDP prievadas dscpFieldsTitle DSCP laukai sipFieldLabel SIP audioRtpStreamFieldLabel Garso RTP srautas videoRtpStreamFieldLabel Vaizdo RTP srautas bandwidthControlTitle Siuntimo spartos valdymas downloadSpeedLimitLabel Atsiuntimo spartos riba, Kbit/sek. uploadSpeedLimitLabel Išsiuntimo spartos riba, Kbit/sek. enableAdaptiveRateControlLabel Įgalinti adaptyviosios normos valdymą presenceTitle Buvimas rlsUriLabel Naudoti RLS URI rlsUriAuto AUTOMATINIS rlsUriDisabled NIEKADA showNetworkSettingsLabel Rodyti tinklo nustatymus generalTitle Bendra SettingsSipAccounts defaultIdentityTitle Numatytoji tapatybė defaultUsernameLabel Naudotojo vardas defaultSipAddressLabel SIP adresas proxyAccountsTitle Įgaliotojo serverio paskyros eraseAllPasswords IŠTRINTI SLAPTAŽODŽIUS addAccount PRIDĖTI PASKYRĄ editHeader Taisyti deleteHeader Ištrinti deleteAccountDescription Ar tikrai norite ištrinti šią paskyrą? eraseAllPasswordsDescription Ar tikrai norite ištrinti visus slaptažodžius? defaultDisplayNameLabel Rodomas vardas assistantTitle Pagelbiklis createAppSipAccountEnabledLabel Įjungti paskyros sukūrimą useAppSipAccountEnabledLabel Įjungti paskyros naudojimą useOtherSipAccountEnabledLabel Įgalinti bendrosios paskyros naudojimą fetchRemoteConfigurationEnabledLabel Įgalinti konfigūracijos gavimą assistantSupportsPhoneNumbersLabel Palaiko telefonų numerius SettingsSipAccountsEdit sipAddressLabel SIP adresas transportLabel Perdavimas serverAddressLabel SIP serverio adresas registrationDurationLabel Registracijos trukmė (sek.) routeLabel Maršrutas contactParamsLabel Kontakto parametrai publishPresenceLabel Paskelbkite informaciją apie buvimą avpfIntervalLabel AVPF įprastas RTCP intervalas (sek.) registerEnabledLabel Registruotis avpfEnabledLabel Įjungti AVPF cancel ATSISAKYTI confirm PATVIRTINTI invalidSipAddress Neteisingas SIP adresas. invalidServerAddress Neteisingas serverio adresas. invalidRoute Netinkamas maršrutas. enableIceLabel Įjungti ICE stunServerLabel STUN/TURN serveris enableTurnLabel Įjungti TURN turnUserLabel TURN naudotojas turnPasswordLabel TURN slaptažodis natAndFirewallTitle NAT ir užkarda mainSipAccountSettingsTitle Pagrindinės SIP paskyros nustatymai SettingsUi pathsTitle Keliai savedScreenshotsLabel Įrašytų ekrano kopijų aplankas savedCallsLabel Išsaugotų skambučių aplankas languagesTitle Kalbos languagesLabel Kalba systemLocale Sistemos lokalės cleanAvatars IŠTRINTI AVATARUS cleanAvatarsDescription Ar tikrai norite ištrinti visus avatarus? downloadLabel Atsiuntimų aplankas setLocaleDescription Yra būtina paleisti programą iš naujo. Ar norite tai atlikti dabar? otherTitle Kita exitOnCloseLabel Užverus langą, išeiti iš programos dataTitle Naudotojo sąsajos duomenys autoStartLabel Automatinio paleidimo programa SettingsVideo videoInputDeviceLabel Vaizdo įvesties įrenginys videoFramerateLabel Kadrų dažnis videoCaptureTitle Vaizdo paėmimo parametrai videoPresetLabel Išankstinės vaizdo parinktys presetDefault Numatytosios presetHighFps Didelis kadr./s skaičius presetCustom Tinkinta videoSizeLabel Vaizdo raiška videoCodecsTitle Vaizdo kodekai showCameraPreview VAIZDO PERŽIŪRA showVideoCodecsLabel Rodyti vaizdo kodekus videoSettingsInCallWarning Vyksta vaizdo skambutis: kai kurie nustatymai negalimi. SettingsVideoPreview confirm GERAI SettingsWindow settingsTitle Nustatymai sipAccountsTab SIP paskyros audioTab Garsas videoTab Vaizdas callsAndChatTab Skambučiai ir pokalbiai networkTab Tinklas uiTab Naudotojo sąsaja validButton GERAI uiAdvanced Išplėstiniai SmartSearchBar addContact PRIDĖTI KONTAKTĄ Timeline timelineTitle Anksčiau UseAppSipAccount confirmAction NAUDOTI useAppSipAccountTitle NAUDOTI %1 SĄSKAITĄ useUsernameToLogin Verčiau naudoti naudotojo vardą ir slaptažodį, o ne telefono numerį. quitWarning Jūsų paskyra buvo sukurta, tačiau dar nebuvo patvirtinta. Ar tikrai norite išeiti iš šio rodinio? UseAppSipAccountWithPhoneNumber countryLabel Šalis phoneNumberLabel Telefono numeris UseAppSipAccountWithUsername usernameLabel Naudotojo vardas passwordLabel Slaptažodis UseOtherSipAccount confirmAction NAUDOTI useOtherSipAccountTitle NAUDOTI SIP PASKYRĄ usernameLabel Naudotojo vardas displayNameLabel Rodomas vardas (nebūtina) sipDomainLabel SIP sritis passwordLabel Slaptažodis transportLabel Perdavimas addOtherSipAccountError Nepavyko pridėti šios paskyros. ZrtpTokenAuthentication confirmSas Patvirtinkite šią SAS su kolega. codeA Sakyk: codeB Jūsų kontaktas turėtų sakyti: deny ATMESTI accept PATVIRTINTI country Afghanistan Albania Algeria AmericanSamoa Andorra Angola Anguilla AntiguaAndBarbuda Argentina Armenia Aruba Australia Austria Azerbaijan Bahamas Bahrain Bangladesh Barbados Belarus Belgium Belize Benin Bermuda Bhutan Bolivia BosniaAndHerzegowina Botswana Brazil Brunei Bulgaria BurkinaFaso Burundi Cambodia Cameroon Canada CapeVerde CaymanIslands CentralAfricanRepublic Chad Chile China Colombia Comoros PeoplesRepublicOfCongo DemocraticRepublicOfCongo CookIslands CostaRica IvoryCoast Croatia Cuba Cyprus CzechRepublic Denmark Djibouti Dominica DominicanRepublic Ecuador Egypt ElSalvador EquatorialGuinea Eritrea Estonia Ethiopia FalklandIslands FaroeIslands Fiji Finland France FrenchGuiana FrenchPolynesia Gabon Gambia Georgia Germany Ghana Gibraltar Greece Greenland Grenada Guadeloupe Guam Guatemala Guinea GuineaBissau Guyana Haiti Honduras HongKong Hungary Iceland India Indonesia Iran Iraq Ireland Israel Italy Jamaica Japan Jordan Kazakhstan Kenya Kiribati DemocraticRepublicOfKorea RepublicOfKorea Kuwait Kyrgyzstan Laos Latvia Lebanon Lesotho Liberia Libya Liechtenstein Lithuania Luxembourg Macau Macedonia Madagascar Malawi Malaysia Maldives Mali Malta MarshallIslands Martinique Mauritania Mauritius Mayotte Mexico Micronesia Moldova Monaco Mongolia Montenegro Montserrat Morocco Mozambique Myanmar Namibia NauruCountry Nepal Netherlands NewCaledonia NewZealand Nicaragua Niger Nigeria Niue NorfolkIsland NorthernMarianaIslands Norway Oman Pakistan Palau PalestinianTerritories Panama PapuaNewGuinea Paraguay Peru Philippines Poland Portugal PuertoRico Qatar Reunion Romania RussianFederation Rwanda SaintHelena SaintKittsAndNevis SaintLucia SaintPierreAndMiquelon SaintVincentAndTheGrenadines Samoa SanMarino SaoTomeAndPrincipe SaudiArabia Senegal Serbia Seychelles SierraLeone Singapore Slovakia Slovenia SolomonIslands Somalia SouthAfrica Spain SriLanka Sudan Suriname Swaziland Sweden Switzerland Syria Taiwan Tajikistan Tanzania Thailand Togo Tokelau Tonga TrinidadAndTobago Tunisia Turkey Turkmenistan TurksAndCaicosIslands Tuvalu Uganda Ukraine UnitedArabEmirates UnitedKingdom UnitedStates Uruguay Uzbekistan Vanuatu Venezuela Vietnam WallisAndFutunaIslands Yemen Zambia Zimbabwe linphone-utils downloadCodecDescription Ar norite atsisiųsti %1 (%2)? linphone-desktop-4.2.5/linphone-app/assets/languages/pt_BR.ts000066400000000000000000002443251376717241300242520ustar00rootroot00000000000000 About ok ESTÁ BEM ActivateAppSipAccountWithEmail activateAppSipAccount ATIVAR A SUA CONTA %1 confirmAction ATIVAR activationSteps Para ativar sua conta: siga as instruções que enviamos em %1 e clique abaixo. ActivateAppSipAccountWithPhoneNumber activateAppSipAccount ATIVAR A SUA CONTA %1 confirmAction ATIVAR activationSteps Um SMS contendo um código de validação foi enviado para %1. Para concluir a verificação do número de telefone, insira o código de 4 dígitos abaixo. App commandLineOptionVerbose log para stdout algumas informações de depuração durante a execução commandLineOptionConfig especificar o arquivo de configuração %1 a ser usado applicationDescription Um telefone de vídeo SIP grátis. commandLineOptionIconified iniciar na bandeja do sistema, não mostrar a interface principal commandLineOptionConfigArg arquivo commandLineOptionHelp mostrar esta ajuda commandLineOptionVersion mostrar versão do aplicativo commandLineOptionCliHelp exibe o menu de ajuda para usar %1 com a CLI commandLineDescription enviar uma ordem para o aplicativo em direção a uma linha de comando restore Restaurar quit Desistir settings Preferências about Sobre AssistantAbstractView back COSTAS AssistantHome useAppSipAccount USAR UMA CONTA %1 useOtherSipAccount USAR UMA CONTA SIP fetchRemoteConfiguration BUSCAR CONFIGURAÇÃO REMOTA homeTitle BEM-VINDOS homeDescription Este assistente irá ajudá-lo a configurar e usar sua conta sip. createAppSipAccount CRIAR UMA CONTA %1 AssistantModel loginWithUsernameFailed Falha no login. Verifique seu nome de usuário/senha. usernameStatusTooShort Muito curto! (%1 caracteres mín.) usernameStatusTooLong Demasiado tempo! (máx.%1 caracteres) usernameStatusInvalidCharacters Caracteres inválidos detectados. (regex: `%1`) usernameStatusInvalid Nome de usuário inválido. passwordStatusTooShort Muito curto! (%1 caracteres mín.) passwordStatusTooLong Demasiado tempo! (máx.%1 caracteres) passwordStatusInvalidCharacters Caracteres inválidos detectados. (regex: `%1`) passwordStatusMissingCharacters Caracteres ausentes: `%1`. requestFailed Não foi possível enviar a solicitação. emailStatusMalformed Endereço de e-mail incorreto. emailStatusMalformedInvalidCharacters Endereço de e-mail incorreto ou caracteres inválidos. cannotSendSms Erro do servidor: não é possível enviar sms. accountAlreadyExists Esta conta já existe. smsActivationFailed Falha na ativação do SMS! emailActivationFailed Verifique se você validou sua conta ou tente novamente. phoneNumberStatusInvalid Número de telefone inválido! phoneNumberStatusTooShort Muito curto! phoneNumberStatusTooLong Demasiado tempo! phoneNumberStatusInvalidCountryCode Código de país inválido! loginWithPhoneNumberFailed Falha no login. Por favor, verifique seu número de telefone. unableToAddAccount Não foi possível adicionar esta conta. AuthenticationRequest cancel CANCELAR confirm LOGIN identityLabel Identidade passwordLabel Senha authenticationRequestDescription Não foi possível autenticar. Verifique sua senha. userIdLabel ID do usuário (opcional) realmLabel Reino CallModel callStatsCodec Codec callStatsUploadBandwidth Largura de banda de upload callStatsDownloadBandwidth Largura de banda de download callStatsEstimatedDownloadBandwidth Largura de banda estimada de download callStatsIceState Estado ICE callStatsIpFamily Família IP callStatsSenderLossRate Taxa de perda do remetente callStatsReceiverLossRate Taxa de perda do receptor callStatsJitterBuffer Buffer de jitter callStatsSentVideoDefinition Definição de vídeo enviada callStatsReceivedVideoDefinition Definição de vídeo recebida iceStateNotActivated Não ativado iceStateFailed Fracassou iceStateInProgress Em curso iceStateReflexiveConnection Conexão reflexiva iceStateHostConnection Conexão do host iceStateRelayConnection Conexão de relé iceStateInvalid Inválido callErrorDeclined O grupo remoto recusou a chamada. callErrorNotFound Grupo remoto não foi encontrado. callErrorBusy A festa remota está ocupada. callErrorNotAcceptable A parte remota não pode aceitar a chamada. callStatsReceivedFramerate Framerate recebido callStatsSentFramerate Framerate enviado CallSipAddress cancel CANCELAR callSipAddressDescription Comece uma nova chamada. CallStatistics audioStatsLabel Áudio videoStatsLabel Vídeo CallTransfer cancel CANCELAR callTransferDescription Deseja transferir esta chamada? Calls acceptAudioCall ACEITAR CHAMADA DE ÁUDIO acceptVideoCall ACEITAR CHAMADA DE VÍDEO terminateCall FINALIZAR CHAMADA resumeCall RETOMAR CHAMADA transferCall CHAMADA DE TRANSFERÊNCIA callPause CHAMADA DE ESPERA CallsWindow callsTitle Ligações acceptClosingDescription Tem certeza de que deseja encerrar todas as chamadas? Chat newMessagePlaceholder Introduza a sua mensagem noFileTransferUrl Não foi possível enviar o arquivo. URL do servidor não configurado. isComposing %1 está a escrever... Cli appCliDescription Maneira de controlar o aplicativo %1 através das linhas de comando. uriCommandLineSyntax %1 <sip-address>?method=<method>([&<argument>=<base64-value>]*) cliCommandLineSyntax %1 "<method> ([<argument> = <value>] *)” commandsName lista de comandos: showFunctionDescription Mostra a janela principal do aplicativo. callFunctionDescription Inicie uma chamada para o endereço do SIP. initiateConferenceFunctionDescription Iniciar uma conferência. joinConferenceFunctionDescription Participe da conferência hospedada pelo sip-address como display-name. Se você estiver conectado a uma configuração de proxy, consulte join-conference-as. joinConferenceAsFunctionDescription Junte-se à conferência organizada pelo sip-address como com o guest-sip-address. Se você não estiver conectado a um proxy-config, consulte join-conference. CodecsViewer codecMime Nome codecEncoderDescription Descrição codecEncoderClockRate Taxa (Hz) codecBitrate Taxa de bits (kbit/s) codecRecvFmtp Parâmetros codecStatus Situação Conference conferenceTitle CONFERÊNCIA ConferenceControls conference CONFERÊNCIA ConferenceManager conferenceManagerDescription Gerencie os participantes da sua conferência. cancel CANCELAR confirm INICIAR ConfirmDialog cancel CANCELAR confirm CONFIRMAR ContactEdit removeContactDescription Deseja realmente remover este contato do seu catálogo de endereços? sipAccounts CONTA (S) SIP address ENDEREÇO emails E-MAIL (S) webSites SITE (S) avatarChooserTitle Escolha o seu avatar companies EMPRESAS save SALVAR cancel CANCELAR sipAccountsPlaceholder Conta SIP companiesPlaceholder Empresa emailsPlaceholder E-mail webSitesPlaceholder Site street Rua postalCode Código postal country País locality Localidade abortEditDescriptionText Tem certeza de que deseja cancelar a modificação de contato? tooltipShowConversation Mostrar conversa Contacts searchContactPlaceholder Pesquisar contato selectAllContacts Todos selectConnectedContacts Conectado addContact ADICIONAR CONTATO removeContactDescription Deseja realmente remover este contato do seu catálogo de endereços? Conversation displayCallsAndMessages TODOS displayCalls CHAMADAS displayMessages MENSAGENS removeAllEntriesDescription Tem certeza de que deseja limpar esse histórico? tooltipContactEdit Editar contato tooltipContactAdd Adicionar contato cleanHistory Excluir histórico CreateAppSipAccount createAppSipAccountDescription Como você gostaria de criar sua conta? createAppSipAccountTitle CRIAR UMA CONTA %1 withPhoneNumber COM UM NÚMERO DE TELEFONE withEmailAddress COM UM ENDEREÇO DE E-MAIL CreateAppSipAccountWithEmail createAppSipAccountTitle CRIAR UMA CONTA %1 confirmAction CRIAR usernameLabel Nome de usuário emailLabel E-mail passwordLabel Senha passwordConfirmationLabel Confirmação de senha passwordConfirmationError As senhas inseridas não correspondem. quitWarning Sua conta foi criada, mas ainda não foi validada. Tem certeza de que deseja sair dessa exibição? displayNameLabel Nome de exibição (opcional) CreateAppSipAccountWithPhoneNumber createAppSipAccountTitle CRIAR UMA CONTA %1 countryLabel País phoneNumberLabel Número de telefone usernameLabel Nome de usuário displayNameLabel Nome de exibição (opcional) confirmAction CRIAR quitWarning Sua conta foi criada, mas ainda não foi validada. Se sair desta vista, terá de adicionar e validar manualmente a sua conta dentro de 24 horas. DroppableTextArea fileChooserTitle Escolha um ou mais arquivos dropYourAttachment Solte seu anexo attachmentTooltip Enviar um arquivo Event incomingCall Chamada recebida outgoingCall Chamada de saída declinedIncomingCall Chamada recebida recusada declinedOutgoingCall Chamada de saída recusada endedCall Chamada encerrada missedIncomingCall Chamada recebida perdida missedOutgoingCall Chamada de saída perdida FetchRemoteConfiguration confirmAction BUSCAR fetchRemoteConfigurationTitle BUSCAR CONFIGURAÇÃO REMOTA urlLabel URL remoteProvisioningError Não é possível definir este uri de provisionamento remoto. remoteProvisioningUpdateDescription É necessário reiniciar o aplicativo. Deseja reiniciar agora? HistoryView removeAllEntriesDescription Tem certeza de que deseja limpar esse histórico? tooltipContactEdit Editar contato tooltipContactAdd Adicionar contato cleanHistory Excluir histórico Home howToDescription Precisa de ajuda para usar o% 1? howToTitle COMO USAR %1 inviteDescription Convide seus amigos em %1. inviteTitle CONVIDE SEUS AMIGOS accountAssistantDescription Crie ou gerencie sua conta %1. accountAssistantTitle ASSISTENTE DE CONTA assistantButton ASSISTENTE showTooltips Mostrar dicas de ferramentas inviteButton CONVIDAR Incall acceptVideoDescription Seu contato gostaria de ativar o vídeo. pendingRequestLabel Aguarde, uma solicitação está pendente. securedStringFormat A chamada está encriptada com: %1. callNotSecured Chamada não criptografada. takeSnapshotLabel Tire uma foto. startRecordingLabel Comece a gravar. stopRecordingLabel Pare de gravar. IncallFullscreenWindow takeSnapshotLabel Tire uma foto. startRecordingLabel Comece a gravar. stopRecordingLabel Pare de gravar. InviteFriends enterEmailLabel Endereço de e-mail do amigo messageLabel Mensagem cancel CANCELAR confirm CONFIRMAR inviteFriendsTitle Convidar amigos defaultMessage %1 quer convidá-lo em %2! defaultSubject Convite de %1 forcedMessage Baixe o aplicativo no seu computador e comece a ligar e conversar com os usuários gratuitamente. Clique aqui: <a href="%1">%1 </a> MainWindow mainSearchBarPlaceholder Pesquisar contato, iniciar uma chamada ou um bate-papo... homeEntry CASA contactsEntry CONTATOS autoAnswerStatus Automático smartSearchBarTooltip Use a barra de pesquisa inteligente para iniciar diretamente o áudio e o vídeo, enviar uma mensagem ou adicionar um novo contato. Basta digitar endereço SIP ou nome de usuário do seu amigo. newConferenceButton Iniciar chamada em conferência MainWindowMenuBar settings Preferências about Sobre quit Desistir MainWindowTopMenuBar settings Preferências about Sobre quit Desistir ManageAccounts ok ESTÁ BEM selectPresenceLabel Status de presença selectAccountLabel Conta ativa Message menuCopy Cópia menuPlayMe Brinca comigo! MultimediaParameters ok ESTÁ BEM Notifier newVersionAvailable Está disponível uma nova versão (%1)! newFileMessage Novo anexo recebido! OnlineInstallerDialog confirm CONFIRMAR onlineInstallerExtractingDescription Extraindo %1... onlineInstallerDownloadingDescription Transferindo %1... onlineInstallerFinishedDescription %1 já está instalado! onlineInstallerFailedDescription Falha ao instalar %1! OutgoingMessage messageError Erro messageRead Leia messageDelivered Entregue Presence presenceOnline Disponível presenceBusy Ocupado presenceDoNotDisturb Não perturbe presenceOffline Offline SettingsAdvanced logsTitle Toros logsFolderLabel Pasta Logs sendLogs ENVIAR LOGS logsUploadUrlLabel URL do servidor de upload de logs logsUploadFailed Falha ao carregar logs. logsEnabledLabel Ativar logs cleanLogs LIMPAR LOGS cleanLogsDescription Tem certeza de que deseja remover todos os logs? developerSettingsTitle Configurações do desenvolvedor developerSettingsEnabledLabel Ativar configurações do desenvolvedor logsMailerFailed Message when Linphone try to open a mailer to send logs, after uploading them to the server (%1 would be the upload url) O mailer não pode ser encontrado, mas os logs foram enviados para %1 logsMailerSuccess Os registos foram enviados para %1 SettingsAudio audioTitle Parâmetros de áudio playbackDeviceLabel Dispositivo de reprodução captureDeviceLabel Capturar dispositivo ringerDeviceLabel Dispositivo de toque ringLabel Anel echoCancellationLabel Ativar cancelamento de eco audioCodecsTitle Codecs de áudio showAudioCodecsLabel Mostrar codecs de áudio playbackGainLabel Ganho de reprodução captureGainLabel Ganho de captura audioTestLabel Nível de captura audioSettingsInCallWarning Chamada de áudio em andamento: algumas configurações não estão disponíveis. SettingsCallsChat fileServerLabel Servidor de arquivos encryptWithLimeLabel Criptografar com LIME limeDisabled Incapacitado limeRequired Obrigatório limePreferred Preferia chatTitle Chat callsTitle Ligações encryptionLabel Criptografia noEncryption Nenhum autoAnswerLabel Resposta automática autoAnswerDelayLabel Atraso (em ms) autoAnswerWithVideoLabel Resposta automática (com vídeo) chatEnabledLabel Ativar bate-papo callRecorderEnabledLabel Ativar gravador de chamadas chatNotificationSoundEnabledLabel Ativar som de notificação chatNotificationSoundLabel Som de notificação conferenceEnabledLabel Ativar conferência contactsTitle Contatos contactsEnabledLabel Ativar contatos muteMicrophoneEnabledLabel Ativar microfone silencioso outgoingCallsEnabledLabel Ativar chamadas de saída showTelKeypadAutomaticallyLabel Mostrar o teclado do telefone automaticamente automaticallyRecordCallsLabel Gravar chamadas automaticamente keepCallsWindowInBackgroundLabel Manter janelas de chamadas em segundo plano callPauseEnabledLabel Retenção de chamada ativada encryptionMandatoryLabel A criptografia é obrigatória SettingsNetwork sendDtmfsLabel método de envio de DTMFS allowIpV6Label Permitir IPv6 transportTitle Transporte natAndFirewallTitle NAT e Firewall enableIceLabel Ativar ICE stunServerLabel Servidor STUN/TUNR enableTurnLabel Ativar Turn turnUserLabel Usuário de Turn turnPasswordLabel Palavra-passe de Turn networkProtocolAndPortsTitle Protocolo de rede e portas sipUdpPortLabel Porta SIP UDP sipTcpPortLabel Porta SIP TCP audioRtpUdpPortLabel Porta UDP de áudio RTP videoRtpUdpPortLabel Porta UDP RTP de vídeo dscpFieldsTitle Campos DSCP sipFieldLabel SABOREIE audioRtpStreamFieldLabel Stream RTP de áudio videoRtpStreamFieldLabel Stream de vídeo RTP bandwidthControlTitle Controle de largura de banda downloadSpeedLimitLabel Limite de velocidade de download em kbit/s uploadSpeedLimitLabel Limite de velocidade de carregamento em kbit/s enableAdaptiveRateControlLabel Ativar controle de taxa adaptável presenceTitle Presença rlsUriLabel Usar URI do RLS rlsUriAuto AUTOMÁTICO rlsUriDisabled NUNCA showNetworkSettingsLabel Mostrar configurações de rede generalTitle Geral SettingsSipAccounts defaultIdentityTitle Identidade padrão defaultUsernameLabel Nome de usuário defaultSipAddressLabel Endereço SIP proxyAccountsTitle Contas proxy eraseAllPasswords REMOVER TODAS AS SENHAS addAccount ADICIONAR CONTA editHeader Editar deleteHeader Excluir deleteAccountDescription Tem certeza de que deseja excluir esta conta? eraseAllPasswordsDescription Tem certeza de que deseja remover todas as senhas? defaultDisplayNameLabel Nome de exibição assistantTitle Assistente createAppSipAccountEnabledLabel Ativar a criação de conta useAppSipAccountEnabledLabel Ativar o uso da conta useOtherSipAccountEnabledLabel Ativar o uso genérico da conta fetchRemoteConfigurationEnabledLabel Ativar busca de configuração assistantSupportsPhoneNumbersLabel Suporta números de telefone SettingsSipAccountsEdit sipAddressLabel Endereço SIP transportLabel Transporte serverAddressLabel Endereço do servidor SIP registrationDurationLabel Duração do registo (seg) routeLabel Rota contactParamsLabel Parâmetros de contato publishPresenceLabel Publicar informações de presença avpfIntervalLabel Intervalo RTCP regular AVPF (seg) registerEnabledLabel Registe-se avpfEnabledLabel Ativar AVPF cancel CANCELAR confirm CONFIRMAR invalidSipAddress Endereço SIP inválido. invalidServerAddress Endereço de servidor inválido. invalidRoute Rota inválida. enableIceLabel Ativar ICE stunServerLabel Servidor STUN/TUNR enableTurnLabel Ativar Turn turnUserLabel Usuário de Turn turnPasswordLabel Palavra-passe de Turn natAndFirewallTitle NAT e Firewall mainSipAccountSettingsTitle Configurações principais da conta SIP SettingsUi pathsTitle Caminhos savedScreenshotsLabel Pasta de capturas de tela salvas savedCallsLabel Pasta de chamadas salvas languagesTitle Línguas languagesLabel Idioma systemLocale Localidade do sistema cleanAvatars APAGAR AVATARES cleanAvatarsDescription Tem certeza de que deseja apagar todos os avatares? downloadLabel Fazer download da pasta setLocaleDescription É necessário reiniciar o aplicativo. Deseja reiniciar agora? otherTitle Outros exitOnCloseLabel Sair da aplicação ao fechar a janela dataTitle Dados da interface do usuário autoStartLabel Aplicação Autostart SettingsVideo videoInputDeviceLabel Dispositivo de entrada de vídeo videoFramerateLabel Framerate videoCaptureTitle Parâmetros de captura de vídeo videoPresetLabel Predefinição de vídeo presetDefault Default presetHighFps Alto FPS presetCustom Personalizado videoSizeLabel Resolução de vídeo videoCodecsTitle Codecs de vídeo showCameraPreview VISUALIZAÇÃO DE VÍDEO showVideoCodecsLabel Mostrar codecs de vídeo videoSettingsInCallWarning Chamada de vídeo em andamento: algumas configurações não estão disponíveis. SettingsVideoPreview confirm ESTÁ BEM SettingsWindow settingsTitle Configurações sipAccountsTab Contas SIP audioTab Áudio videoTab Vídeo callsAndChatTab Chamadas e bate-papo networkTab Rede uiTab Interface do usuário validButton ESTÁ BEM uiAdvanced Avançado SmartSearchBar addContact ADICIONAR CONTATO Timeline timelineTitle Anteriormente.. UseAppSipAccount confirmAction USO useAppSipAccountTitle USAR UMA CONTA %1 useUsernameToLogin Use nome de usuário e senha em vez de seu número de telefone. quitWarning Sua conta foi criada, mas ainda não foi validada. Tem certeza de que deseja sair dessa exibição? UseAppSipAccountWithPhoneNumber countryLabel País phoneNumberLabel Número de telefone UseAppSipAccountWithUsername usernameLabel Nome de usuário passwordLabel Senha UseOtherSipAccount confirmAction USO useOtherSipAccountTitle USAR UMA CONTA SIP usernameLabel Nome de usuário displayNameLabel Nome de exibição (opcional) sipDomainLabel Domínio SIP passwordLabel Senha transportLabel Transporte addOtherSipAccountError Não foi possível adicionar esta conta. ZrtpTokenAuthentication confirmSas Confirme o seguinte SAS com peer. codeA Diga: codeB Seu contato deve dizer: deny NEGAR accept CONFIRMAR country Afghanistan Afeganistão Albania Albânia Algeria Argélia AmericanSamoa Americanos Amoa Andorra Andorra Angola Angola Anguilla Anguila AntiguaAndBarbuda Antiguae Barbuda Argentina Argentina Armenia Arménia Aruba Aruba Australia Austrália Austria Áustria Azerbaijan Azerbaijão Bahamas Bahamas Bahrain Barém Bangladesh Bangladesh Barbados Barbados Belarus Bielorrússia Belgium Bélgica Belize Belize Benin Benim Bermuda Bermudas Bhutan Butão Bolivia Bolívia BosniaAndHerzegowina Bósnia e Herzegowina Botswana Botsuana Brazil Brasil Brunei Brunei Bulgaria Bulgária BurkinaFaso Burkinafaso Burundi Burúndi Cambodia Camboja Cameroon Camarões Canada Canadá CapeVerde Cabo Verde CaymanIslands Ilhas Caymanas CentralAfricanRepublic República Centro-Africana Chad Chade Chile Chile China China Colombia Colômbia Comoros Comores PeoplesRepublicOfCongo República do Congo DemocraticRepublicOfCongo República Democrática do Congo CookIslands Ilhas Cookies CostaRica Costa Rica IvoryCoast Costa do Marfim Croatia Croácia Cuba Cuba Cyprus Chipre CzechRepublic República Tcheca Denmark Dinamarca Djibouti Djibuti Dominica Dominica DominicanRepublic República Dominicana Ecuador Equador Egypt Egito ElSalvador El Salvador EquatorialGuinea Guiné Equatorial Eritrea Eritreia Estonia Estónia Ethiopia Etiópia FalklandIslands Malvinas FaroeIslands Ilhas Faroé Fiji Fiji Finland Finlândia France França FrenchGuiana Francesa Guiana FrenchPolynesia Polinésia Francesa Gabon Gabão Gambia Gâmbia Georgia Geórgia Germany Alemanha Ghana Gana Gibraltar Gibraltar Greece Grécia Greenland Gronelândia Grenada Granada Guadeloupe Guadalupe Guam Guam Guatemala Guatemala Guinea Guiné GuineaBissau Guiné-Bissau Guyana Guiana Haiti Haiti Honduras Honduras HongKong Hong Kong Hungary Hungria Iceland Islândia India Índia Indonesia Indonésia Iran Irã Iraq Iraque Ireland Irlanda Israel Israel Italy Itália Jamaica Jamaica Japan Japão Jordan Jordânia Kazakhstan Cazaquistão Kenya Quênia Kiribati Kiribati DemocraticRepublicOfKorea Democratica República da Coreia RepublicOfKorea República da Coreia Kuwait Kuwait Kyrgyzstan Quirguizistão Laos Laos Latvia Letónia Lebanon Líbano Lesotho Lesoto Liberia Libéria Libya Líbia Liechtenstein Liechtenstein Lithuania Lituânia Luxembourg Luxemburgo Macau Macau Macedonia Macedónia Madagascar Madagascar Malawi Malawi Malaysia Malásia Maldives Maldivas Mali Mali Malta Malta MarshallIslands Ilhas Marshallis Martinique Martinica Mauritania Mauritânia Mauritius Maurícia Mayotte Mayotte Mexico México Micronesia Micronésia Moldova Moldávia Monaco Mónaco Mongolia Mongólia Montenegro Montenegro Montserrat Monserrate Morocco Marrocos Mozambique Moçambique Myanmar Mianmar Namibia Namíbia NauruCountry Nauru Nepal Nepal Netherlands Holanda NewCaledonia Nova Caledônia NewZealand Nova Zelândia Nicaragua Nicarágua Niger Níger Nigeria Nigéria Niue Niue NorfolkIsland Ilha Norfolk NorthernMarianaIslands Ilhas do Norte da Mariana Norway Noruega Oman Omã Pakistan Paquistão Palau Palau PalestinianTerritories Palestinianos anteriores Panama Panamá PapuaNewGuinea Papua Nova Guiné Paraguay Paraguai Peru Peru Philippines Filipinas Poland Polónia Portugal Portugal PuertoRico Porto Rico Qatar Catar Reunion Reunião Romania Roménia RussianFederation Federação Russa Rwanda Ruanda SaintHelena Santa Lena SaintKittsAndNevis São Cristóvão e Nevis SaintLucia Santa Lucia SaintPierreAndMiquelon São Pedro e Miquelon SaintVincentAndTheGrenadines São Vicente e Granadinas Samoa Samoa SanMarino São Marino SaoTomeAndPrincipe São Tomé e Príncipe SaudiArabia Arábia Saudita Senegal Senegal Serbia Sérvia Seychelles Seicheles SierraLeone Serra Leoa Singapore Singapura Slovakia Eslováquia Slovenia Eslovénia SolomonIslands Ilhas Salomão Somalia Somália SouthAfrica África do Sul Spain Espanha SriLanka Sri Lanka Sudan Sudão Suriname Suriname Swaziland Suazilândia Sweden Suécia Switzerland Suíça Syria Síria Taiwan Taiwan Tajikistan Tajiquistão Tanzania Tanzânia Thailand Tailândia Togo Togo Tokelau Tokelau Tonga Tonga TrinidadAndTobago Trinidad e Tobago Tunisia Tunísia Turkey Turquia Turkmenistan Turquemenistão TurksAndCaicosIslands Ilhas Turcas e Caicos Tuvalu Tuvalu Uganda Uganda Ukraine Ucrânia UnitedArabEmirates Emirados Árabes Unidos UnitedKingdom Reino Unido UnitedStates Estados Unidos Uruguay Uruguai Uzbekistan Uzbequistão Vanuatu Vanuatu Venezuela Venezuela Vietnam Vietname WallisAndFutunaIslands Ilhas Wallis e Futuna Yemen Iémen Zambia Zâmbia Zimbabwe Zimbabué linphone-utils downloadCodecDescription Deseja transferir %1 (%2)? linphone-desktop-4.2.5/linphone-app/assets/languages/ru.ts000066400000000000000000002666471376717241300237050ustar00rootroot00000000000000 About ok OK ActivateAppSipAccountWithEmail activateAppSipAccount АКТИВИРУЙТЕ ВАШ АККАУНТ %1 confirmAction АКТИВИРОВАТЬ activationSteps Чтобы активировать аккаунт, следуйте инструкциям, которые мы отправили на %1, затем нажмите ниже. ActivateAppSipAccountWithPhoneNumber activateAppSipAccount АКТИВИРУЙТЕ ВАШ АККАУНТ %1 confirmAction АКТИВИРОВАТЬ activationSteps Мы отправили SMS с кодом подтверждения на %1. Для завершения подтверждения вашего номера телефона, пожалуйста, введите ниже 4-значный код. App commandLineOptionVerbose выводить в stdout некоторую отладочную информацию во время работы commandLineOptionConfig укажите конфигурационный файл %1 applicationDescription Свободное приложение для SIP видео звонков. commandLineOptionIconified запускать свёрнутой в область уведомлений, не показывать основной инфтерфейс commandLineOptionConfigArg файл commandLineOptionHelp показать эту справку commandLineOptionVersion показать версию приложения commandLineOptionCliHelp показывает меню помощи в использовании %1 из командной строки commandLineDescription отправка команды приложения через командную строку restore Восстановить quit Выйти settings Настройки about О программе AssistantAbstractView back НАЗАД AssistantHome useAppSipAccount ИСПОЛЬЗОВАТЬ АККАУНТ %1 useOtherSipAccount ИСПОЛЬЗОВАТЬ SIP АККАУНТ fetchRemoteConfiguration ЗАГРУЗИТЬ УДАЛЁННУЮ КОНФИГУРАЦИЮ homeTitle ДОБРО ПОЖАЛОВАТЬ homeDescription Этот ассистент поможет вам настроить и использовать ваш аккаунт %1. createAppSipAccount СОЗДАТЬ АККАУНТ %1 AssistantModel loginWithUsernameFailed Не удалось войти. Пожалуйста, проверьте правильность ввода имени пользователя и пароля. usernameStatusTooShort Слишком короткое! (мин. %1 символов) usernameStatusTooLong Слишком длинное! (макс. %1 символов) usernameStatusInvalidCharacters Обнаружены недопустимые символы. (regex: `%1`) usernameStatusInvalid Недопустимое имя пользователя. passwordStatusTooShort Слишком короткий! (мин. %1 символов) passwordStatusTooLong Слишком длинный! (макс. %1 символов) passwordStatusInvalidCharacters Обнаружены недопустимые символы. (regex: `%1`) passwordStatusMissingCharacters Не хватает символов: `%1`. requestFailed Не удалось отправить запрос. emailStatusMalformed Недопустимый адрес почты. emailStatusMalformedInvalidCharacters Недопустимый адрес почты или недопустимые символы. cannotSendSms Ошибка сервера: не удалось отправить SMS. accountAlreadyExists Такой аккаунт уже существует. smsActivationFailed SMS активация не удалась! emailActivationFailed Пожалуйста, удостоверьтесь в том, что вы подтвердили ваш аккаунт, или попробуйте снова. phoneNumberStatusInvalid Недопустимый номер телефона! phoneNumberStatusTooShort Слишком короткий! phoneNumberStatusTooLong Слишком длинный! phoneNumberStatusInvalidCountryCode Недопустимый код страны! loginWithPhoneNumberFailed Не удалось войти. Пожалуйста проверьте правильность ввода номера телефона. unableToAddAccount Не удалось добавить этот аккаунт. AuthenticationRequest cancel ОТМЕНА confirm ВОЙТИ identityLabel Логин passwordLabel Пароль authenticationRequestDescription Не удалось выполнить аутентификацию. Пожалуйста, проверьте правильность ввода пароля. userIdLabel ID пользователя (не обязательно) realmLabel Область CallModel callStatsCodec Кодек callStatsUploadBandwidth Исходящая скорость callStatsDownloadBandwidth Входящая скорость callStatsEstimatedDownloadBandwidth Предполагаемая входящая скорость callStatsIceState Состояние ICE callStatsIpFamily Семейство IP callStatsSenderLossRate Потери исходящих пакетов callStatsReceiverLossRate Потери входящих пакетов callStatsJitterBuffer Буфер колебаний задержки callStatsSentVideoDefinition Разрешение исходящего видео callStatsReceivedVideoDefinition Разрешение входящего видео iceStateNotActivated Не активирован iceStateFailed Неудачно iceStateInProgress В процессе iceStateReflexiveConnection Рефлексивное соединение iceStateHostConnection Подключение хоста iceStateRelayConnection Релейное соединение iceStateInvalid Недопустимый callErrorDeclined Удалённая сторона отклонила вызов. callErrorNotFound Удалённая сторона не найдена. callErrorBusy Удалённая сторона занята. callErrorNotAcceptable Удалённая сторона не может принять вызов. callStatsReceivedFramerate Входящая частота кадров callStatsSentFramerate Исходящая частота кадров CallSipAddress cancel ОТМЕНА callSipAddressDescription Начать новый вызов. CallStatistics audioStatsLabel Аудио videoStatsLabel Видео CallTransfer cancel ОТМЕНА callTransferDescription Хотите перенаправить этот вызов? Calls acceptAudioCall ПРИНЯТЬ АУДИО ВЫЗОВ acceptVideoCall ПРИНЯТЬ ВИДЕО ВЫЗОВ terminateCall ЗАВЕРШИТЬ ВЫЗОВ resumeCall ПРОДОЛЖИТЬ ВЫЗОВ transferCall ПЕРНАПРАВИТЬ ВЫЗОВ callPause ПРИОСТАНОВИТЬ ВЫЗОВ CallsWindow callsTitle Звонки acceptClosingDescription Вы уверены, что хотите завершить все вызовы? Chat newMessagePlaceholder Введите сообщение noFileTransferUrl Не удалось отправить файл. Не настроен адрес сервера. isComposing %1 печатает... Cli appCliDescription Способ управлять %1 через командную строку. uriCommandLineSyntax %1 sip:<адрес-sip>?method=<метод>([&<аргумент>=<base64-значение>]*) cliCommandLineSyntax %1 "<метод> ([<аргумент>=<значение>]*)" commandsName список команд: showFunctionDescription Показать главное окно приложения. callFunctionDescription Начать вызов SIP адреса. initiateConferenceFunctionDescription Начать конференцию. joinConferenceFunctionDescription Присоединитесь к конференции по sip-адресу. Если вы подключены к конфигурации прокси, см. join-conference-as. joinConferenceAsFunctionDescription Присоединитесь к конференции по sip-адресу. Если вы не подключены к конфигурации прокси, см. join-conference-as. CodecsViewer codecMime Название codecEncoderDescription Описание codecEncoderClockRate Частота (Гц) codecBitrate Битрейт (Кбит/с) codecRecvFmtp Параметры codecStatus Статус Conference conferenceTitle КОНФЕРЕНЦИЯ ConferenceControls conference КОНФЕРЕНЦИЯ ConferenceManager conferenceManagerDescription Управляйте участниками вашей конференции. cancel ОТМЕНА confirm НАЧАТЬ ConfirmDialog cancel ОТМЕНА confirm ПОДТВЕРДИТЬ ContactEdit removeContactDescription Вы действительно хотите удалить этот контакт из вашей адресной книги? sipAccounts SIP АККАУНТ(Ы) address АДРЕС emails E-MAIL webSites САЙТ(Ы) avatarChooserTitle Выберите ваш аватар companies КОМПАНИИ save СОХРАНИТЬ cancel ОТМЕНА sipAccountsPlaceholder SIP аккаунт companiesPlaceholder Компания emailsPlaceholder Email webSitesPlaceholder Сайт street Улица postalCode Почтовый индекс country Страна locality Населённый пункт abortEditDescriptionText Вы уверены, что хотите отменить изменение контакта? tooltipShowConversation Показать разговор Contacts searchContactPlaceholder Найти контакт selectAllContacts Все selectConnectedContacts Подключенные addContact ДОБАВИТЬ КОНТАКТ removeContactDescription Вы действительно хотите удалить этот контакт из вашей адресной книги? Conversation displayCallsAndMessages ВСЕ displayCalls ВЫЗОВЫ displayMessages СООБЩЕНИЯ removeAllEntriesDescription Вы уверены, что хотите очистить эту историю? tooltipContactEdit Изменить контакт tooltipContactAdd Добавить контакт cleanHistory Удалить историю CreateAppSipAccount createAppSipAccountDescription Как бы вы хотели создать аккаунт? createAppSipAccountTitle СОЗДАТЬ АККАУНТ %1 withPhoneNumber С ПОМОЩЬЮ НОМЕРА ТЕЛЕФОНА withEmailAddress С ПОМОЩЬЮ EMAIL CreateAppSipAccountWithEmail createAppSipAccountTitle СОЗДАТЬ АККАУНТ %1 confirmAction СОЗДАТЬ usernameLabel Имя пользователя emailLabel Email passwordLabel Пароль passwordConfirmationLabel Подтверждение пароля passwordConfirmationError Введённые пароли не совпадают quitWarning Ваш аккаунт был создан, но ещё не подтверждён. Вы уверены, что хотите выйти? displayNameLabel Отображаемое имя (не обязательно) CreateAppSipAccountWithPhoneNumber createAppSipAccountTitle СОЗДАТЬ АККАУНТ %1 countryLabel Страна phoneNumberLabel Номер телефона usernameLabel Имя пользователя displayNameLabel Отображаемое имя (не обязательно) confirmAction СОЗДАТЬ quitWarning Ваш аккаунт был создан, но ещё не подтверждён. Если вы выйдете, вам потребуется вручную добавить и подтвердить свой аккаунт в течении 24 часов. DroppableTextArea fileChooserTitle Пожалуйста, выберите один или несколько файлов. dropYourAttachment Поместите вложение attachmentTooltip Отправить файл Event incomingCall Входящий вызов outgoingCall Исходящий вызов declinedIncomingCall Отклонённый входящий вызов declinedOutgoingCall Отклонённый исходящий вызов endedCall Завершённый вызов missedIncomingCall Пропущенный входящий вызов missedOutgoingCall Пропущенный исходящий вызов FetchRemoteConfiguration confirmAction ЗАГРУЗИТЬ fetchRemoteConfigurationTitle ЗАГРУЗИТЬ УДАЛЁННУЮ КОНФИГУРАЦИЮ urlLabel URL remoteProvisioningError Невозможно установить эту удалённую настройку uri. remoteProvisioningUpdateDescription Требуется перезапустить приложение. Хотите перезапустить сейчас? HistoryView removeAllEntriesDescription Вы уверены, что хотите очистить эту историю? tooltipContactEdit Изменить контакт tooltipContactAdd Добавить контакт cleanHistory Удалить историю Home howToDescription Нужна помощь в использовании %1? howToTitle КАК ПОЛЬЗОВАТЬСЯ %1 inviteDescription Пригласите друзей использовать %1. inviteTitle ПРИГЛАСИТЕ ДРУЗЕЙ accountAssistantDescription Создание и управление аккаунтом %1. accountAssistantTitle АССИСТЕНТ АККАУНТА assistantButton АССИСТЕНТ showTooltips Показывать подсказки inviteButton ПРИГЛАСИТЬ Incall acceptVideoDescription Ваш контакт хотел бы включить видео. pendingRequestLabel Пожалуйста, подождите, запрос обрабатывается. securedStringFormat Вызов сшифрован с: %1. callNotSecured Вызов не зашифрован. takeSnapshotLabel Сделать снимок. startRecordingLabel Начать запись. stopRecordingLabel Остановить запись. IncallFullscreenWindow takeSnapshotLabel Сделать снимок. startRecordingLabel Начать запись. stopRecordingLabel Остановить запись. InviteFriends enterEmailLabel Email друга messageLabel Сообщение cancel ОТМЕНА confirm ПОДТВЕРДИТЬ inviteFriendsTitle Пригласить друзей defaultMessage %1 приглашает вас использовать %2 ! defaultSubject Приглащение %1 forcedMessage Загрузите приложение на ваш компьютер и начните звонить и общаться бесплатно. Ссылка для загрузки: <a href="%1">%1</a> MainWindow mainSearchBarPlaceholder Найти контакт, начать звонок или чат… homeEntry ГЛАВНАЯ contactsEntry КОНТАКТЫ autoAnswerStatus авто smartSearchBarTooltip Используйте умную поисковую строку, чтобы сразу начать аудио или видео вызов, отправить сообщение или добавить новый контакт. Просто введите SIP адрес или имя пользователя вашего контакта. newConferenceButton Начать конференц звонок MainWindowMenuBar settings Настройки about О программе quit Выйти MainWindowTopMenuBar settings Предпочтения about О quit Уйти ManageAccounts ok OK selectPresenceLabel Статус selectAccountLabel Активный аккаунт Message menuCopy Копировать menuPlayMe Играй! MultimediaParameters ok OK Notifier newVersionAvailable Доступна новая (%1) версия! newFileMessage Получен новый файл! OnlineInstallerDialog confirm ПОДТВЕРДИТЬ onlineInstallerExtractingDescription Извлечение %1… onlineInstallerDownloadingDescription Загрузка %1… onlineInstallerFinishedDescription %1 установлен! onlineInstallerFailedDescription Не удалось установить %1! OutgoingMessage messageError Ошибка messageRead Прочитано messageDelivered Доставлено Presence presenceOnline Доступен presenceBusy Занят presenceDoNotDisturb Не беспокоить presenceOffline Офлайн SettingsAdvanced logsTitle Журналы logsFolderLabel Папка журналов sendLogs ОТПРАВКА ЖУРНАЛОВ logsUploadUrlLabel URL севрера для отправки журналов logsUploadFailed Не удалось отправить журналы logsEnabledLabel Журналы включены cleanLogs УДАЛИТЬ ЖУРНАЛЫ cleanLogsDescription Вы уверены, что хотите удалить все журналы? developerSettingsTitle Настройки для разработчиков developerSettingsEnabledLabel Включить настройки для разработчиков logsMailerFailed Message when Linphone try to open a mailer to send logs, after uploading them to the server (%1 would be the upload url) Не удалось найти почтовый ящик, но журналы были загружены в %1 logsMailerSuccess Журналы были загружены в %1 SettingsAudio audioTitle Параметры аудио playbackDeviceLabel Устройство воспроизведения captureDeviceLabel Устройство захвата ringerDeviceLabel Устройство звонка ringLabel Звонок echoCancellationLabel Включить подавление эха audioCodecsTitle Аудио кодеки showAudioCodecsLabel Показать Аудио кодаки playbackGainLabel Усил воспроизведения captureGainLabel Прирост захвата audioTestLabel Уровень захвата audioSettingsInCallWarning Звуковой вызов в процессе: некоторые настройки недоступны. SettingsCallsChat fileServerLabel Файловый сервер encryptWithLimeLabel Шифровать с помощью LIME limeDisabled Отключено limeRequired Обязательно limePreferred Предпочтительно chatTitle Чат callsTitle Звонки encryptionLabel Шифрование noEncryption Нет autoAnswerLabel Принимать вызов автоматически autoAnswerDelayLabel Задержка (в мс) autoAnswerWithVideoLabel Принимать вызов автоматически (с видео) chatEnabledLabel Включить чат callRecorderEnabledLabel Включить запись звонков chatNotificationSoundEnabledLabel Включить звук уведомлений chatNotificationSoundLabel Звук уведомлений conferenceEnabledLabel Включить конференцию contactsTitle Контакты contactsEnabledLabel Включить контакты muteMicrophoneEnabledLabel Выключить микрофон outgoingCallsEnabledLabel Включение исходящих вызовов showTelKeypadAutomaticallyLabel Показывать телефонную клавиатуру автоматически automaticallyRecordCallsLabel Автоматически записывать звонки keepCallsWindowInBackgroundLabel Поддерживать звонки в свернутом режиме callPauseEnabledLabel Вызов поставлен на паузу encryptionMandatoryLabel Регистрация обязательна SettingsNetwork sendDtmfsLabel Метод отправки DTMF allowIpV6Label Разрешить IPv6 transportTitle Транспорт natAndFirewallTitle NAT и межсетевой экран enableIceLabel Включить ICE stunServerLabel Сервер STUN/TURN enableTurnLabel Включить TURN turnUserLabel Пользователь TURN turnPasswordLabel Пароль TURN networkProtocolAndPortsTitle Сетевой протокол и порты sipUdpPortLabel UDP порт SIP sipTcpPortLabel TCP порт SIP audioRtpUdpPortLabel UDP порт RTP аудио videoRtpUdpPortLabel UDP порт RTP видео dscpFieldsTitle Поля DSCP sipFieldLabel SIP audioRtpStreamFieldLabel Поток RTP аудио videoRtpStreamFieldLabel Поток RTP видео bandwidthControlTitle Управление полосой пропускания downloadSpeedLimitLabel Ограничить входящую скорость до Кбит/сек uploadSpeedLimitLabel Ограничить исходящую скорость до Кбит/сек enableAdaptiveRateControlLabel Включить адаптивное управление скоростью presenceTitle Статус rlsUriLabel Использовать RLS URI rlsUriAuto АВТО rlsUriDisabled НИКОГДА showNetworkSettingsLabel Показать сетевые настройки generalTitle Основные SettingsSipAccounts defaultIdentityTitle Удостоверение по умолчанию defaultUsernameLabel Имя пользователя defaultSipAddressLabel Адрес SIP proxyAccountsTitle Прокси аккаунты eraseAllPasswords УДАЛИТЬ ПАРОЛИ addAccount ДОБАВИТЬ АККАУНТ editHeader Изменить deleteHeader Удалить deleteAccountDescription Вы уверены, что хотите удалить этот аккаунт? eraseAllPasswordsDescription Вы уверены, что хотите удалить все пароли? defaultDisplayNameLabel Отображаемое имя assistantTitle Помощник createAppSipAccountEnabledLabel Включить создание аккаунта useAppSipAccountEnabledLabel Включить использования аккаунта useOtherSipAccountEnabledLabel Включить использование общего аккаунта fetchRemoteConfigurationEnabledLabel Включить выбор конфигурации assistantSupportsPhoneNumbersLabel Поддерживает номера телефонов SettingsSipAccountsEdit sipAddressLabel Адрес SIP transportLabel Транспорт serverAddressLabel Адрес сервера SIP registrationDurationLabel Длительность регистрациии (сек) routeLabel Маршрут contactParamsLabel Контактные параметры publishPresenceLabel Публиковать статус avpfIntervalLabel AVPF обычный RTCP интервал (сек) registerEnabledLabel Регистрация avpfEnabledLabel Включить AVPF cancel ОТМЕНА confirm ПОДТВЕРДИТЬ invalidSipAddress Недопустимый SIP адрес. invalidServerAddress Недопустимый адрес сервера. invalidRoute Неверный маршрут. enableIceLabel Включить ICE stunServerLabel Сервер STUN/TURN enableTurnLabel Включить TURN turnUserLabel Пользователь TURN turnPasswordLabel Пароль TURN natAndFirewallTitle NAT и межсетевой экран mainSipAccountSettingsTitle Основные настройки SIP аккаунта SettingsUi pathsTitle Пути savedScreenshotsLabel Папка для сохранения снимков savedCallsLabel Папка для записи звонков languagesTitle Языки languagesLabel Язык systemLocale Системный cleanAvatars УДАЛИТЬ АВАТАРЫ cleanAvatarsDescription Вы уверены, что хотите удалить все аватары? downloadLabel Папка для сохранения загрузок setLocaleDescription Необходим перезапуск программы. Хотите перезапустить сейчас? otherTitle Прочее exitOnCloseLabel Завершать программу при закрытии окна dataTitle Данные пользовательского интерфейса autoStartLabel Автозапуск SettingsVideo videoInputDeviceLabel Устройство-источник видео videoFramerateLabel Частота кадров videoCaptureTitle Параметры захвата видео videoPresetLabel Пресет видео presetDefault По умолчанию presetHighFps Высокая частота кадров presetCustom Настраиваемый videoSizeLabel Разрешение видео videoCodecsTitle Видео кодеки showCameraPreview ПРЕДПРОСМОТР ВИДЕО showVideoCodecsLabel Показать Видео кодаки videoSettingsInCallWarning Видеозвонок выполняется: некоторые настройки недоступны. SettingsVideoPreview confirm OK SettingsWindow settingsTitle Настройки sipAccountsTab SIP аккаунты audioTab Аудио videoTab Видео callsAndChatTab Звонки и чат networkTab Сеть uiTab Интерфейс validButton OK uiAdvanced Дополнительные SmartSearchBar addContact ДОБАВИТЬ КОНТАКТ Timeline timelineTitle Ранее UseAppSipAccount confirmAction ИСПОЛЬЗОВАТЬ useAppSipAccountTitle ИСПОЛЬЗОВАТЬ АККАУНТ %1 useUsernameToLogin Использовать имя пользователя и пароль вместо номера телефона. quitWarning Ваш аккаунт был создан, но ещё не подтверждён. Вы уверены, что хотите выйти? UseAppSipAccountWithPhoneNumber countryLabel Страна phoneNumberLabel Номер телефона UseAppSipAccountWithUsername usernameLabel Имя пользователя passwordLabel Пароль UseOtherSipAccount confirmAction ИСПОЛЬЗОВАТЬ useOtherSipAccountTitle ИСПОЛЬЗОВАТЬ SIP АККАУНТ usernameLabel Имя пользователя displayNameLabel Отображаемое имя (не обязательно) sipDomainLabel Домен SIP passwordLabel Пароль transportLabel Транспорт addOtherSipAccountError Не удалось добавить этот аккаунт. ZrtpTokenAuthentication confirmSas Подтвердите следующую строку аутентификации с контактом. codeA Скажите: codeB Ваш контакт должен сказать: deny ОТКЛОНИТЬ accept ПОДТВЕРДИТЬ country Afghanistan Афганистан Albania Албания Algeria Алжир AmericanSamoa Американское Самоа Andorra Андорра Angola Ангола Anguilla Ангилья AntiguaAndBarbuda Антигуа и Барбуда Argentina Аргентина Armenia Армения Aruba Аруба Australia Австралия Austria Австрия Azerbaijan Азербайджан Bahamas Багамы Bahrain Бахрейн Bangladesh Бангладеш Barbados Барбадос Belarus Беларусь Belgium Бельгия Belize Белиз Benin Бенин Bermuda Бермуды Bhutan Бутан Bolivia Боливия BosniaAndHerzegowina Босния и Герцеговина Botswana Ботсвана Brazil Бразилия Brunei Бруней Bulgaria Болгария BurkinaFaso Буркина-Фасо Burundi Бурунди Cambodia Камбоджа Cameroon Камерун Canada Канада CapeVerde Кабо-Верде CaymanIslands Каймановы острова CentralAfricanRepublic Центральноафриканская Республика Chad Чад Chile Чили China Китай Colombia Колумбия Comoros Коморы PeoplesRepublicOfCongo Республика Конго DemocraticRepublicOfCongo Демократическая Республика Конго CookIslands Острова Кука CostaRica Коста-Рика IvoryCoast Берег Слоновой Кости Croatia Хорватия Cuba Куба Cyprus Кипр CzechRepublic Чешская Республика Denmark Дания Djibouti Джибути Dominica Доминика DominicanRepublic Доминиканская Республика Ecuador Эквадор Egypt Египет ElSalvador Сальвадор EquatorialGuinea Экваториальная Гвинея Eritrea Эритрея Estonia Эстония Ethiopia Эфиопия FalklandIslands Фолклендские острова FaroeIslands Фарерские острова Fiji Фиджи Finland Финляндия France Франция FrenchGuiana Французская Гвиана FrenchPolynesia Французская Полинезия Gabon Габон Gambia Гамбия Georgia Грузия Germany Германия Ghana Гана Gibraltar Гибралтар Greece Греция Greenland Гренландия Grenada Гренада Guadeloupe Гваделупа Guam Гуам Guatemala Гватемала Guinea Гвинея GuineaBissau Гвинея-Бисау Guyana Гайана Haiti Гаити Honduras Гондурас HongKong Гонконг Hungary Венгрия Iceland Исландия India Индия Indonesia Индонезия Iran Иран Iraq Ирак Ireland Ирландия Israel Израиль Italy Италия Jamaica Ямайка Japan Япония Jordan Иордания Kazakhstan Казахстан Kenya Кения Kiribati Кирибати DemocraticRepublicOfKorea Демократическая Республика Корея RepublicOfKorea Республика Корея Kuwait Кувейт Kyrgyzstan Кыргызстан Laos Лаос Latvia Латвия Lebanon Ливан Lesotho Лесото Liberia Либерия Libya Ливия Liechtenstein Лихтенштейн Lithuania Литва Luxembourg Люксембург Macau Макао Macedonia Македония Madagascar Мадагаскар Malawi Малави Malaysia Малайзия Maldives Мальдивы Mali Мали Malta Мальта MarshallIslands Маршалловы Острова Martinique Мартиника Mauritania Мавритания Mauritius Маврикий Mayotte Майотта Mexico Мексика Micronesia Микронезия Moldova Молдова Monaco Монако Mongolia Монголия Montenegro Черногория Montserrat Монсеррат Morocco Марокко Mozambique Мозамбик Myanmar Мьянма Namibia Намибия NauruCountry Науру Nepal Непал Netherlands Нидерланды NewCaledonia Новая Каледония NewZealand Новая Зеландия Nicaragua Никарагуа Niger Нигер Nigeria Нигерия Niue Ниуэ NorfolkIsland Остров Норфолк NorthernMarianaIslands Северные Марианские острова Norway Норвегия Oman Оман Pakistan Пакистан Palau Палау PalestinianTerritories Палестинские территории Panama Панама PapuaNewGuinea Папуа-Новая Гвинея Paraguay Парагвай Peru Перу Philippines Филиппины Poland Польша Portugal Португалия PuertoRico Пуэрто-Рико Qatar Катар Reunion Воссоединение Romania Румыния RussianFederation Российская Федерация Rwanda Руанда SaintHelena Остров Святой Елены SaintKittsAndNevis Сент-Китс и Невис SaintLucia Сент-Люсия SaintPierreAndMiquelon Сен-Пьер и Микелон SaintVincentAndTheGrenadines Сент-Винсент и Гренадины Samoa Самоа SanMarino Сан-Марино SaoTomeAndPrincipe Сан-Томе и Принсипи SaudiArabia Саудовская Аравия Senegal Сенегал Serbia Сербия Seychelles Сейшелы SierraLeone Сьерра-Леоне Singapore Сингапур Slovakia Словакия Slovenia Словения SolomonIslands Соломоновы Острова Somalia Сомали SouthAfrica Южная Африка Spain Испания SriLanka Шри-Ланка Sudan Судан Suriname Суринам Swaziland Свазиленд Sweden Швеция Switzerland Швейцария Syria Сирия Taiwan Тайвань Tajikistan Таджикистан Tanzania Танзания Thailand Таиланд Togo Того Tokelau Токелау Tonga Тонга TrinidadAndTobago Тринидад и Тобаго Tunisia Тунис Turkey Турция Turkmenistan Туркменистан TurksAndCaicosIslands Острова Теркс и Кайкос Tuvalu Тувалу Uganda Уганда Ukraine Украина UnitedArabEmirates Объединенные Арабские Эмираты UnitedKingdom Соединенное Королевство UnitedStates Соединенные Штаты Америки Uruguay Уругвай Uzbekistan Узбекистан Vanuatu Вануату Venezuela Венесуэла Vietnam Вьетнам WallisAndFutunaIslands Острова Уоллис и Футуна Yemen Йемен Zambia Замбия Zimbabwe Зимбабве linphone-utils downloadCodecDescription Хотите загрузить %1 (%2)? linphone-desktop-4.2.5/linphone-app/assets/languages/sv.ts000066400000000000000000002426401376717241300236720ustar00rootroot00000000000000 About ok OK ActivateAppSipAccountWithEmail activateAppSipAccount AKTIVERA DITT %1-KONTO confirmAction AKTIVERA activationSteps För att aktivera ditt konto: Följ anvisningarna som vi skickade till %1, och klicka sedan nedan. ActivateAppSipAccountWithPhoneNumber activateAppSipAccount AKTIVERA DITT %1-KONTO confirmAction AKTIVERA activationSteps Vi har skickat ett SMS med en valideringskod till %1. För att slutföra din telefonnummerverifiering, ange den 4-siffriga koden nedan. App commandLineOptionVerbose logga till stdout viss felsökningsinformation under körning commandLineOptionConfig specificera %1 konfigurationsfilen som skall användas applicationDescription En gratis (libre) SIP-videotelefon. commandLineOptionIconified starta i systemfältet, visa inte huvudgränssnittet commandLineOptionConfigArg fil commandLineOptionHelp visa denna hjälp commandLineOptionVersion visa appversion commandLineOptionCliHelp Visar hjälpmenyn för att använda %1 med kommandotolken commandLineDescription skicka en order till programmet via en kommandrad restore Återställ quit Avsluta settings Inställningar about Om AssistantAbstractView back TILLBAKA AssistantHome useAppSipAccount ANVÄND ETT %1-KONTO useOtherSipAccount ANVÄND ETT SIP-KONTO fetchRemoteConfiguration HÄMTA FJÄRRKONFIGURATION homeTitle VÄLKOMMEN homeDescription Denna assistent hjälper dig att konfigurera och använda ditt %1-konto. createAppSipAccount SKAPA ETT %1-KONTO AssistantModel loginWithUsernameFailed Inloggningen misslyckades. Kontrollera ditt användarnamn/lösenord. usernameStatusTooShort För kort! (minst %1 tecken) usernameStatusTooLong För långt! (max %1 tecken) usernameStatusInvalidCharacters Ogiltiga tecken upptäckta. (regex: `%1`) usernameStatusInvalid Ogiltigt användarnamn. passwordStatusTooShort För kort! (minst %1 tecken) passwordStatusTooLong För långt! (max %1 tecken) passwordStatusInvalidCharacters Ogiltiga tecken upptäckta. (regex: `%1`) passwordStatusMissingCharacters Saknade tecken: `%1`. requestFailed Det gick inte att skicka förfrågan. emailStatusMalformed Felaktig e-postadress. emailStatusMalformedInvalidCharacters Felaktig e-postadress eller ogiltiga tecken. cannotSendSms Serverfel: det går inte att skicka sms. accountAlreadyExists Detta konto finns redan. smsActivationFailed SMS-aktivering misslyckades! emailActivationFailed Kontrollera att du har validerat ditt konto eller försök igen. phoneNumberStatusInvalid Ogiltigt telefonnummer! phoneNumberStatusTooShort För kort! phoneNumberStatusTooLong För långt! phoneNumberStatusInvalidCountryCode Ogiltig landskod! loginWithPhoneNumberFailed Inloggningen misslyckades. Kolla ditt telefonnummer. unableToAddAccount Det gick inte att lägga till det här kontot. AuthenticationRequest cancel AVBRYT confirm LOGGA IN identityLabel Identitet passwordLabel Lösenord authenticationRequestDescription Det går inte att autentisera. Verifiera ditt lösenord. userIdLabel Användar-ID (valfritt) realmLabel Domän CallModel callStatsCodec Kodek callStatsUploadBandwidth Sändningsbandbredd callStatsDownloadBandwidth Hämtningsbandbredd callStatsEstimatedDownloadBandwidth Beräknad hämtningsbandbredd callStatsIceState ICE-tillstånd callStatsIpFamily IP-familj callStatsSenderLossRate Förlusthastighet för avsändare callStatsReceiverLossRate Förlusthastighet för mottagare callStatsJitterBuffer Skakbuffert callStatsSentVideoDefinition Skickad videodefinition callStatsReceivedVideoDefinition Mottagen videodefinition iceStateNotActivated Inte aktiverad iceStateFailed Misslyckades iceStateInProgress Pågående iceStateReflexiveConnection Reflexiv anslutning iceStateHostConnection Värdanslutning iceStateRelayConnection Reläanslutning iceStateInvalid Ogiltig callErrorDeclined Fjärrparten avböjde samtalet. callErrorNotFound Fjärrparten hittades inte. callErrorBusy Fjärrparten är upptagen. callErrorNotAcceptable Fjärrparten kan inte acceptera samtalet. callStatsReceivedFramerate Mottagen bildfrekvens callStatsSentFramerate Skickad bildfrekvens CallSipAddress cancel AVBRYT callSipAddressDescription Starta ett nytt samtal. CallStatistics audioStatsLabel Ljud videoStatsLabel Video CallTransfer cancel AVBRYT callTransferDescription Vill du överföra detta samtalet? Calls acceptAudioCall ACCEPTERA LJUDSAMTAL acceptVideoCall ACCEPTERA VIDEOSAMTAL terminateCall LÄGG PÅ resumeCall ÅTERUPPTA SAMTAL transferCall ÖVERFÖR SAMTAL callPause PAUSA SAMTAL CallsWindow callsTitle Samtal acceptClosingDescription Är du säker på att du vill avsluta alla samtal? Chat newMessagePlaceholder Ange ditt meddelande noFileTransferUrl Det gick inte att skicka filen. Serverwebbadressen är inte konfigurerad. isComposing %1 skriver... Cli appCliDescription Sätt att styra %1-programmet via kommandoraden. uriCommandLineSyntax %1-<sip-address>?method=<method>([&<argument>=<base64-value>]*) cliCommandLineSyntax %1 "<method> ([<argument>=<value>]*)" commandsName lista över kommandon : showFunctionDescription Visa huvudfönstret av programmet. callFunctionDescription Starta ett samtal till sip-adressen. initiateConferenceFunctionDescription Starta en konferens. joinConferenceFunctionDescription Gå med i konferensen som sip-adressen är värd för, som visningsnamn. Om du är ansluten till en proxy-konfiguration, se gå-med-i-konferens-som. joinConferenceAsFunctionDescription Gå med i konferensen som sip-adressen står som värd för med gäst-sip-adress. Om du inte är ansluten till en proxy-konfiguration, see gå-med-i-konferens. CodecsViewer codecMime Namn codecEncoderDescription Beskrivning codecEncoderClockRate Hastighet (Hz) codecBitrate Bithastighet (Kbit/s) codecRecvFmtp Parametrar codecStatus Status Conference conferenceTitle KONFERENS ConferenceControls conference KONFERENS ConferenceManager conferenceManagerDescription Hantera deltagare till din konferens. cancel AVBRYT confirm BÖRJA ConfirmDialog cancel AVBRYT confirm BEKRÄFTA ContactEdit removeContactDescription Vill du verkligen ta bort denna kontakt från din adressbok? sipAccounts SIP-KONTO(N) address ADRESS emails E-POSTADRESS(ER) webSites WEBBPLATS(ER) avatarChooserTitle Välj din avatar companies FÖRETAG save SPARA cancel AVBRYT sipAccountsPlaceholder SIP-konto companiesPlaceholder Företag emailsPlaceholder E-post webSitesPlaceholder Webbplats street Väg postalCode Postnummer country Land locality Lokalitet abortEditDescriptionText Är du säker på att du vill avbryta kontaktändringen? tooltipShowConversation Visa konversation Contacts searchContactPlaceholder Sök kontakt selectAllContacts Alla selectConnectedContacts Ansluten addContact LÄGG TILL KONTAKT removeContactDescription Vill du verkligen ta bort denna kontakt från din adressbok? Conversation displayCallsAndMessages ALLA displayCalls SAMTAL displayMessages MEDDELANDEN removeAllEntriesDescription Är du säker på att du vill rensa den här historiken? tooltipContactEdit Redigera kontakt tooltipContactAdd Lägg till kontakt cleanHistory Radera historik CreateAppSipAccount createAppSipAccountDescription Hur vill du skapa ditt konto? createAppSipAccountTitle SKAPA ETT %1-KONTO withPhoneNumber MED ETT TELEFONNUMMER withEmailAddress MED E-POSTADRESS CreateAppSipAccountWithEmail createAppSipAccountTitle SKAPA ETT %1-KONTO confirmAction SKAPA usernameLabel Användarnamn emailLabel E-post passwordLabel Lösenord passwordConfirmationLabel Lösenordsbekräftelse passwordConfirmationError Lösenorden du angav matchade inte. quitWarning Ditt konto har skapats men har ännu inte validerats. Är du säker på att du vill avsluta den här vyn? displayNameLabel Visningsnamn (valfritt) CreateAppSipAccountWithPhoneNumber createAppSipAccountTitle SKAPA ETT %1-KONTO countryLabel Land phoneNumberLabel Telefonnummer usernameLabel Användarnamn displayNameLabel Visningsnamn (valfritt) confirmAction SKAPA quitWarning Ditt konto har skapats men har ännu inte validerats. Om du avslutar den här vyn måste du manuellt lägga till och validera ditt konto inom 24 timmar. DroppableTextArea fileChooserTitle Välj en eller flera filer dropYourAttachment Släpp din bilaga attachmentTooltip Skicka en fil Event incomingCall Inkommande samtal outgoingCall Utgående samtal declinedIncomingCall Avböjt inkommande samtal declinedOutgoingCall Avböjt utgående samtal endedCall Avslutat samtal missedIncomingCall Missat inkommande samtal missedOutgoingCall Missat utgående samtal FetchRemoteConfiguration confirmAction HÄMTA fetchRemoteConfigurationTitle HÄMTA FJÄRRKONFIGURATION urlLabel WEBBADRESS remoteProvisioningError Kan inte sätta denna fjärravsättnings-uri. remoteProvisioningUpdateDescription Det är nödvändigt att starta om programmet. Vill du starta om nu? HistoryView removeAllEntriesDescription Är du säker på att du vill rensa den här historiken? tooltipContactEdit Redigera kontakt tooltipContactAdd Lägg till kontakt cleanHistory Radera historik Home howToDescription Behöver du hjälp med hur du använder %1? howToTitle HUR DU ANVÄNDER %1 inviteDescription Bjud in dina vänner på %1. inviteTitle BJUD IN DINA VÄNNER accountAssistantDescription Skapa eller hantera ditt %1-konto. accountAssistantTitle KONTO ASSISTENT assistantButton ASSISTENT showTooltips Visa verktygstips inviteButton BJUD IN Incall acceptVideoDescription Din kontakt vill gärna slå på video. pendingRequestLabel Vänta, en förfrågan väntar. securedStringFormat Samtalet är krypterat med: %1. callNotSecured Samtal inte krypterat. takeSnapshotLabel Ta en ögonblicksbild. startRecordingLabel Börja inspelning. stopRecordingLabel Stoppa inspelning. IncallFullscreenWindow takeSnapshotLabel Ta en ögonblicksbild. startRecordingLabel Börja inspelning. stopRecordingLabel Stoppa inspelning. InviteFriends enterEmailLabel Väns e-postadress messageLabel Meddelande cancel AVBRYT confirm BEKRÄFTA inviteFriendsTitle Bjud in vänner defaultMessage %1 vill bjuda in dig på %2! defaultSubject %1 inbjudan forcedMessage Hämta programmet på din dator och börja ringa och chatta med %1-användare gratis. Klicka här: <a href="%1">%1</a> MainWindow mainSearchBarPlaceholder Sök kontakt, starta ett samtal eller en chatt... homeEntry HEM contactsEntry KONTAKTER autoAnswerStatus automatiskt smartSearchBarTooltip Använd det intelligenta sökfältet för att omedelbart starta ljud- och videosamtal, skicka ett meddelande, eller lägga till en ny kontakt. Ange helt enkelt din väns SIP-adress eller användarnamn. newConferenceButton Starta konferenssamtal MainWindowMenuBar settings Inställningar about Om quit Avsluta MainWindowTopMenuBar settings Inställningar about Ungefär quit Sluta ManageAccounts ok OK selectPresenceLabel Närvarostatus selectAccountLabel Aktivt konto Message menuCopy Kopiera menuPlayMe Spela mig! MultimediaParameters ok OK Notifier newVersionAvailable En ny version (%1) är tillgänglig! newFileMessage Ny bilaga mottagen! OnlineInstallerDialog confirm BEKRÄFTA onlineInstallerExtractingDescription Extraherar %1... onlineInstallerDownloadingDescription Hämtar %1... onlineInstallerFinishedDescription % 1 är nu installerad! onlineInstallerFailedDescription Misslyckades med att installera% 1! OutgoingMessage messageError Fel messageRead Läs messageDelivered Levererad Presence presenceOnline Tillgänglig presenceBusy Upptagen presenceDoNotDisturb Stör inte presenceOffline Frånkopplad SettingsAdvanced logsTitle Loggar logsFolderLabel Loggmapp sendLogs SKICKA LOGGAR logsUploadUrlLabel Server-URL för loggar logsUploadFailed Misslyckades med att sända loggar. logsEnabledLabel Aktivera loggar cleanLogs RENSA LOGGAR cleanLogsDescription Är du säker på att du vill ta bort alla loggar? developerSettingsTitle Utvecklarinställningar developerSettingsEnabledLabel Aktivera utvecklarinställningar logsMailerFailed Message when Linphone try to open a mailer to send logs, after uploading them to the server (%1 would be the upload url) Mailer kan inte hittas, men loggarna laddades upp till %1 logsMailerSuccess Loggar laddades upp till %1 SettingsAudio audioTitle Ljudparametrar playbackDeviceLabel Uppspelningsenhet captureDeviceLabel Inspelningsenhet ringerDeviceLabel Ringenhet ringLabel Ring echoCancellationLabel Aktivera ekodämpning audioCodecsTitle Ljudkodek showAudioCodecsLabel Visa ljudkodek playbackGainLabel Uppspelning captureGainLabel Fånga vinst audioTestLabel Fånga nivå audioSettingsInCallWarning Ljudsamtal pågår: vissa inställningar är inte tillgängliga. SettingsCallsChat fileServerLabel Filserver encryptWithLimeLabel Kryptera med LIME limeDisabled Inaktiverad limeRequired Obligatorisk limePreferred Föredraget chatTitle Chatt callsTitle Samtal encryptionLabel Kryptering noEncryption Inga autoAnswerLabel Automatiskt svar autoAnswerDelayLabel Fördröjning (i ms) autoAnswerWithVideoLabel Automatiskt svar (med video) chatEnabledLabel Aktivera chatt callRecorderEnabledLabel Aktivera samtalsinspelare chatNotificationSoundEnabledLabel Aktivera aviseringsljud chatNotificationSoundLabel Aviseringsljud conferenceEnabledLabel Aktivera konferens contactsTitle Kontakter contactsEnabledLabel Aktivera kontakter muteMicrophoneEnabledLabel Aktivera tysta mikrofon outgoingCallsEnabledLabel Aktivera utgående samtal showTelKeypadAutomaticallyLabel Visa telefonens knappsats automatiskt automaticallyRecordCallsLabel Spela in samtal automatiskt keepCallsWindowInBackgroundLabel Behåll samtalsfönster i bakgrunden callPauseEnabledLabel Håll samtal aktiverat encryptionMandatoryLabel Kryptering är obligatorisk SettingsNetwork sendDtmfsLabel DTMF:s sändningsmetod allowIpV6Label Tillåt IPv6 transportTitle Transport natAndFirewallTitle NAT och brandvägg enableIceLabel Aktivera ICE stunServerLabel STUN/TURN-server enableTurnLabel Aktivera TURN turnUserLabel TURN-användare turnPasswordLabel TURN-lösenord networkProtocolAndPortsTitle Nätverksprotokoll och portar sipUdpPortLabel SIP UDP-port sipTcpPortLabel SIP TCP-port audioRtpUdpPortLabel Ljud-RTP UDP-port videoRtpUdpPortLabel Video-RTP UDP-port dscpFieldsTitle DSCP-fält sipFieldLabel SIP audioRtpStreamFieldLabel Audio RTP-ström videoRtpStreamFieldLabel Video RTP-ström bandwidthControlTitle Bandbreddskontroll downloadSpeedLimitLabel Hämtningshastighetsgräns i Kbit/sek uploadSpeedLimitLabel Sändningshastighetsgräns i Kbit/sek enableAdaptiveRateControlLabel Aktivera adaptiv hastighetskontroll presenceTitle Närvaro rlsUriLabel Använd RLS-URI rlsUriAuto AUTOMATISKT rlsUriDisabled ALDRIG showNetworkSettingsLabel Visa nätverksinställningar generalTitle Allmänt SettingsSipAccounts defaultIdentityTitle Standardidentitet defaultUsernameLabel Användarnamn defaultSipAddressLabel SIP-adress proxyAccountsTitle Proxy-konton eraseAllPasswords RADERA LÖSENORD addAccount LÄGG TILL KONTO editHeader Redigera deleteHeader Ta bort deleteAccountDescription Är du säker på att du vill radera detta konto? eraseAllPasswordsDescription Är du säker på att du vill radera alla lösenord? defaultDisplayNameLabel Visningsnamn assistantTitle Assistent createAppSipAccountEnabledLabel Aktivera kontoupprättning useAppSipAccountEnabledLabel Aktivera kontoanvändning useOtherSipAccountEnabledLabel Aktivera generisk kontoanvändning fetchRemoteConfigurationEnabledLabel Aktivera konfigurationshämtning assistantSupportsPhoneNumbersLabel Stöder telefonnummer SettingsSipAccountsEdit sipAddressLabel SIP-adress transportLabel Transport serverAddressLabel SIP-serveradress registrationDurationLabel Registreringsvaraktighet (sek) routeLabel Rutt contactParamsLabel Kontaktparametrar publishPresenceLabel Publicera närvaroinformation avpfIntervalLabel AVPF normalt RTCP-intervall (sek) registerEnabledLabel Registrera avpfEnabledLabel Aktivera AVPF cancel AVBRYT confirm BEKRÄFTA invalidSipAddress Ogiltig SIP-adress. invalidServerAddress Ogiltig serveradress. invalidRoute Ogiltig rutt. enableIceLabel Aktivera ICE stunServerLabel STUN/TURN-server enableTurnLabel Aktivera TURN turnUserLabel TURN-användare turnPasswordLabel TURN-lösenord natAndFirewallTitle NAT och brandvägg mainSipAccountSettingsTitle Huvud SIP-kontoinställningar SettingsUi pathsTitle Sökvägar savedScreenshotsLabel Mapp med sparade skärmdumpar savedCallsLabel Mapp med sparade samtal languagesTitle Språk languagesLabel Språk systemLocale Systemlokal cleanAvatars RADERA AVATARER cleanAvatarsDescription Är du säker på att du vill radera alla avatarer? downloadLabel Hämtningsmapp setLocaleDescription Det är nödvändigt att starta om programmet. Vill du starta om nu? otherTitle Annat exitOnCloseLabel Avsluta app på stäng fönster dataTitle Användargränssnittsdata autoStartLabel Autostarta appen SettingsVideo videoInputDeviceLabel Videoinmatningsenhet videoFramerateLabel Bildfrekvens videoCaptureTitle Videoinspelningsparametrar videoPresetLabel Videoförinställning presetDefault Standard presetHighFps Hög FPS presetCustom Anpassad videoSizeLabel Videoupplösning videoCodecsTitle Videokodekar showCameraPreview VIDEOFÖRHANDSVISNING showVideoCodecsLabel Visa videokodekar videoSettingsInCallWarning Videosamtal pågår: vissa inställningar är inte tillgängliga. SettingsVideoPreview confirm OK SettingsWindow settingsTitle Inställningar sipAccountsTab SIP-konto audioTab Ljud videoTab Video callsAndChatTab Samtal och chatt networkTab Nätverk uiTab Användargränssnitt validButton OK uiAdvanced Avancerat SmartSearchBar addContact LÄGG TILL KONTAKT Timeline timelineTitle Tidigare UseAppSipAccount confirmAction ANVÄND useAppSipAccountTitle ANVÄND ETT %1-KONTO useUsernameToLogin Använd användarnamn och lösenord istället för ditt telefonnummer. quitWarning Ditt konto har skapats men har ännu inte validerats. Är du säker på att du vill avsluta den här vyn? UseAppSipAccountWithPhoneNumber countryLabel Land phoneNumberLabel Telefonnummer UseAppSipAccountWithUsername usernameLabel Användarnamn passwordLabel Lösenord UseOtherSipAccount confirmAction ANVÄND useOtherSipAccountTitle ANVÄND ETT SIP-KONTO usernameLabel Användarnamn displayNameLabel Visningsnamn (valfritt) sipDomainLabel SIP-domän passwordLabel Lösenord transportLabel Transport addOtherSipAccountError Det gick inte att lägga till det här kontot. ZrtpTokenAuthentication confirmSas Bekräfta följande SAS med partner codeA Säg: codeB Din kontaktperson bör säga: deny FÖRNEKA accept BEKRÄFTA country Afghanistan Afghanistan Albania Albanien Algeria Algeriet AmericanSamoa Amerikanska Samoa Andorra Andorra Angola Angola Anguilla Anguilla AntiguaAndBarbuda Antigua och Barbuda Argentina Argentina Armenia Armenien Aruba Aruba Australia Australien Austria Österrike Azerbaijan Azerbajdzjan Bahamas - Bahamas Bahrain Bahrain Bangladesh Bangladesh Barbados Barbados Belarus Vitryssland Belgium Belgien Belize Belize Benin Benin Bermuda Bermuda Bhutan Bhutan Bolivia Bolivia BosniaAndHerzegowina Bosnien och Hercegovina Botswana Botswana Brazil Brasilien Brunei Brunei Bulgaria Bulgarien BurkinaFaso Burkina Faso Burundi Burundi Cambodia Kambodja Cameroon Kamerun Canada Kanada CapeVerde Kap Verde CaymanIslands Caymanöarna CentralAfricanRepublic Centralafrikanska republiken Chad Tchad Chile Chile China Kina Colombia Colombia Comoros Komorerna PeoplesRepublicOfCongo Republiken Kongo DemocraticRepublicOfCongo Demokratiska republiken Kongo CookIslands Cooköarna CostaRica Costa Rica IvoryCoast Elfenbenskusten Croatia Kroatien Cuba Kuba Cyprus Cypern CzechRepublic Tjeckien Denmark Danmark Djibouti Djibouti Dominica Dominica DominicanRepublic Dominikanska republiken Ecuador Ecuador Egypt Egypten ElSalvador El Salvador EquatorialGuinea Ekvatorialguinea Eritrea Eritrea Estonia Estland Ethiopia Etiopien FalklandIslands Falklandsöarna FaroeIslands Färöarna Fiji Fiji Finland Finland France Frankrike FrenchGuiana Franska Guyana FrenchPolynesia Franska Polynesien Gabon Gabon Gambia Gambia Georgia Georgien Germany Tyskland Ghana Ghana Gibraltar Gibraltar Greece Grekland Greenland Grönland Grenada Grenada Guadeloupe Guadeloupe Guam Guam Guatemala Guatemala Guinea Guinea GuineaBissau Guinea-Bissau Guyana Guyana Haiti Haiti Honduras Honduras HongKong Hongkong Hungary Ungern Iceland Island India Indien Indonesia Indonesien Iran Iran Iraq Irak Ireland Irland Israel Israel Italy Italien Jamaica Jamaica Japan Japan Jordan Jordanien Kazakhstan Kazakstan Kenya Kenya Kiribati Kiribati DemocraticRepublicOfKorea Demokratiska republiken Korea RepublicOfKorea Republiken Korea Kuwait Kuwait Kyrgyzstan Kirgizistan Laos Laos Latvia Lettland Lebanon Libanon Lesotho Lesotho Liberia Liberia Libya Libyen Liechtenstein Liechtenstein Lithuania Litauen Luxembourg Luxemburg Macau Macao Macedonia Makedonien Madagascar Madagaskar Malawi Malawi Malaysia Malaysia Maldives Maldiverna Mali Mali Malta Malta MarshallIslands Marshallöarna Martinique Martinique Mauritania Mauretanien Mauritius Mauritius Mayotte Mayotte Mexico Mexiko Micronesia Mikronesien Moldova Moldavien Monaco Monaco Mongolia Mongoliet Montenegro Montenegro Montserrat Montserrat Morocco Marocko Mozambique Moçambique Myanmar Myanmar Namibia Namibia NauruCountry Nauru Nepal Nepal Netherlands Nederländerna NewCaledonia Nya Kaledonien NewZealand Nya Zeeland Nicaragua Nicaragua Niger Niger Nigeria Nigeria Niue Niue NorfolkIsland Norfolkön NorthernMarianaIslands Nordmarianerna Norway Norge Oman Oman Pakistan Pakistan Palau Palau PalestinianTerritories Palestinska territorier Panama Panama PapuaNewGuinea Papua Nya Guinea Paraguay Paraguay Peru Peru Philippines Filippinerna Poland Polen Portugal Portugal PuertoRico Puerto Rico Qatar Qatar Reunion Återförening Romania Rumänien RussianFederation Ryssland Rwanda Rwanda SaintHelena Sankt Helena SaintKittsAndNevis Saint Kitts och Nevis SaintLucia Saint Lucia SaintPierreAndMiquelon Saint-Pierre och Miquelon SaintVincentAndTheGrenadines Saint Vincent Och Grenadinerna Samoa Samoa SanMarino San Marino SaoTomeAndPrincipe São Tomé och Principe SaudiArabia Saudiarabien Senegal Senegal Serbia Serbien Seychelles Seychellerna SierraLeone Sierra Leone Singapore Singapore Slovakia Slovakien Slovenia Slovenien SolomonIslands Salomonöarna Somalia Somalia SouthAfrica Sydafrika Spain Spanien SriLanka Sri Lanka Sudan Sudan Suriname Surinam Swaziland Swaziland Sweden Sverige Switzerland Schweiz Syria Syrien Taiwan Taiwan Tajikistan Tadzjikistan Tanzania Tanzania Thailand Thailand Togo Togo Tokelau Tokelau Tonga Tonga TrinidadAndTobago Trinidad Och Tobago Tunisia Tunisien Turkey Kalkon Turkmenistan Turkmenistan TurksAndCaicosIslands Turks- och Caicosöarna Tuvalu Tuvalu Uganda Uganda Ukraine Ukraina UnitedArabEmirates Förenade Arabemiraten UnitedKingdom Förenade kungariket UnitedStates USA Uruguay Uruguay Uzbekistan Uzbekistan Vanuatu Vanuatu Venezuela Venezuela Vietnam Vietnam WallisAndFutunaIslands Wallis- och Futunaöarna Yemen Jemen Zambia Zambia Zimbabwe Zimbabwe linphone-utils downloadCodecDescription Vill du hämta %1 (%2)? linphone-desktop-4.2.5/linphone-app/assets/languages/tr.ts000066400000000000000000002447441376717241300236760ustar00rootroot00000000000000 About ok TAMAM ActivateAppSipAccountWithEmail activateAppSipAccount %1 HESABINIZI ETKİNLEŞTİRİN confirmAction ETKİNLEŞTİR activationSteps Hesabınızı etkinleştirmek için: %1 adresine gönderdiğimiz yönergeleri takip edin ardından aşağıdakine tıklayın. ActivateAppSipAccountWithPhoneNumber activateAppSipAccount %1 HESABINIZI ETKİNLEŞTİRİN confirmAction ETKİNLEŞTİR activationSteps %1 numarasına doğrulama kodu içeren SMS gönderdik. Telefon numarası doğrulamanızı tamamlamak için lütfen 4 haneli kodu aşağıya girin. App commandLineOptionVerbose çalışırken bazı hata ayıklama bilgilerini stdout'a günlükle commandLineOptionConfig kullanılacak %1 yapılandırma dosyasını belirt applicationDescription Özgür SIP görüntülü telefonu. commandLineOptionIconified sistem tepsisinde başla, ana arayüzü gösterme commandLineOptionConfigArg dosya commandLineOptionHelp bu yardımı göster commandLineOptionVersion uygulama sürümünü göster commandLineOptionCliHelp %1'u komut satırı arayüzüyle kullanmak için yardım menüsünü gösterir commandLineDescription komut satırıyla uygulamaya emir gönder restore Kurtar quit Çıkış settings Tercihler about Hakkında AssistantAbstractView back GERİ AssistantHome useAppSipAccount %1 HESABI KULLAN useOtherSipAccount SIP HESABI KULLAN fetchRemoteConfiguration UZAKTAN YAPILANDIRMA AL homeTitle HOŞ GELDİNİZ homeDescription Bu yardımcı, %1 hesabınızı yapıldırmanız ve kullanmanız için size yardım edecek. createAppSipAccount %1 HESABI OLUŞTUR AssistantModel loginWithUsernameFailed Giriş başarısız. Lütfen kullanıcı adı/parolanızı denetleyin. usernameStatusTooShort Çok kısa! (en az %1 karakter) usernameStatusTooLong Çok uzun! (en çok %1 karakter) usernameStatusInvalidCharacters Geçersiz karakter saptandı. (regex: `%1`) usernameStatusInvalid Geçersiz kullanıcı adı. passwordStatusTooShort Çok kısa! (en az %1 karakter) passwordStatusTooLong Çok uzun! (en çok %1 karakter) passwordStatusInvalidCharacters Geçersiz karakter saptandı. (regex: `%1`) passwordStatusMissingCharacters Eksik karakterler: `%1`. requestFailed İstek gönderilemiyor. emailStatusMalformed Doğru olmayan e-posta adresi. emailStatusMalformedInvalidCharacters Doğru olmayan e-posta adresi veya geçersiz karakterler. cannotSendSms Sunucu hatası: sms gönderilemedi accountAlreadyExists Bu hesap zaten var. smsActivationFailed SMS etkinleştirme başarısız! emailActivationFailed Lütfen hesabınızı doğruladığınızı onaylayın veya yeniden deneyin. phoneNumberStatusInvalid Geçersiz telefon numarası! phoneNumberStatusTooShort Çok kısa! phoneNumberStatusTooLong Çok uzun! phoneNumberStatusInvalidCountryCode Geçersiz ülke kodu! loginWithPhoneNumberFailed Giriş başarısız. Lütfen telefon numaranızı denetleyin. unableToAddAccount Bu hesap eklenemiyor. AuthenticationRequest cancel İPTAL confirm GİR identityLabel Kimlik passwordLabel Parola authenticationRequestDescription Yetkilendirilemiyor. Lütfen parolanızı onaylayın. userIdLabel Kullanıcı kimliği (isteğe bağlı) realmLabel Yetki alanı CallModel callStatsCodec Çözücü callStatsUploadBandwidth Yükleme bant genişliği callStatsDownloadBandwidth İndirme bant genişliği callStatsEstimatedDownloadBandwidth Hesaplanan indirme bant genişliği callStatsIceState ICE durumu callStatsIpFamily IP ailesi callStatsSenderLossRate Gönderici kayıp oranı callStatsReceiverLossRate Alıcı kayıp oranı callStatsJitterBuffer Gecikme arabelleği callStatsSentVideoDefinition Giden görüntü tanımı callStatsReceivedVideoDefinition Alınan görüntü tanımı iceStateNotActivated Etkin değil iceStateFailed Başarısız iceStateInProgress Sürüyor iceStateReflexiveConnection Dönüşlü bağlantı iceStateHostConnection Ana makine bağlantısı iceStateRelayConnection Röle bağlantısı iceStateInvalid Geçersiz callErrorDeclined Uzak şahıs çağrıyı reddetti. callErrorNotFound Uzak şahıs bulunamadı. callErrorBusy Uzak şahıs meşgul. callErrorNotAcceptable Uzak şahıs çağrıyı kabul edemez. callStatsReceivedFramerate Alınan çerçeve oranı callStatsSentFramerate Giden çerçeve oranı CallSipAddress cancel İPTAL callSipAddressDescription Yeni çağrı başlat. CallStatistics audioStatsLabel Ses videoStatsLabel Görüntü CallTransfer cancel İPTAL callTransferDescription Bu çağrıyı aktarmak ister misiniz? Calls acceptAudioCall SESLİ ÇAĞRIYI KABUL ET acceptVideoCall GÖRÜNTÜLÜ ÇAĞRIYI KABUL ET terminateCall TELEFONU KAPAT resumeCall ÇAĞRIYI DEVAM ETTİR transferCall ÇAĞRIYI AKTAR callPause ÇAĞRIYI DURAKLAT CallsWindow callsTitle Çağrılar acceptClosingDescription Tüm çağrılara son vermek istediğinize emin misiniz? Chat newMessagePlaceholder İletinizi girin noFileTransferUrl Dosya gönderilemiyor. Sunucu url'si yapılandırılmadı. isComposing %1 yazıyor... Cli appCliDescription %1 uygulamasını komut satırlarıyla denetleme yolu. uriCommandLineSyntax %1 <sip-address>?method=<method>([&<argument>=<base64-value>]*) cliCommandLineSyntax %1 "<method> ([<argument>=<value>]*)" commandsName komut listesi: showFunctionDescription Uygulamanın ana penceresini göster. callFunctionDescription Sip adresine çağrı başlat. initiateConferenceFunctionDescription Toplantı başlat. joinConferenceFunctionDescription Sip adresinin ev sahipliğindeki toplantıya görünen ad ile katıl. Eğer vekil yapılandırmaya bağlandıysanız "toplantıya şunun ile katıl"a bakın. joinConferenceAsFunctionDescription Sip adresinin ev sahipliğindeki toplantıya misafir sip adresi ile katıl. Eğer vekil yapılandırmaya bağlandıysanız "toplantıya-katıl"a bakın. CodecsViewer codecMime Ad codecEncoderDescription Açıklama codecEncoderClockRate Oran (Hz) codecBitrate Bit oranı (Kbit/s) codecRecvFmtp Parametreler codecStatus Durum Conference conferenceTitle TOPLANTI ConferenceControls conference TOPLANTI ConferenceManager conferenceManagerDescription Toplantı katılımcılarınızı yönetin. cancel İPTAL confirm BAŞLAT ConfirmDialog cancel İPTAL confirm ONAYLA ContactEdit removeContactDescription Bu kişiyi adres defterinizden silmek istediğinize emin misiniz? sipAccounts SIP HESAPLARI address ADRES emails E-POSTA(LAR) webSites WEB SİTE(LERİ) avatarChooserTitle Avatarınızı seçin companies ŞİRKETLER save KAYDET cancel İPTAL sipAccountsPlaceholder SIP hesabı companiesPlaceholder Şirket emailsPlaceholder E-posta webSitesPlaceholder Web site street Sokak postalCode Posta kodu country Ülke locality Semt abortEditDescriptionText Kişi düzenlemesini iptal etmek istediğinize emin misiniz? tooltipShowConversation Sohbeti göster Contacts searchContactPlaceholder Kişi ara selectAllContacts Tümü selectConnectedContacts Bağlı addContact KİŞİ EKLE removeContactDescription Bu kişiyi adres defterinizden silmek istediğinize emin misiniz? Conversation displayCallsAndMessages TÜMÜ displayCalls ÇAĞRILAR displayMessages İLETİLER removeAllEntriesDescription Bu geçmişi temizlemek istediğinize emin misiniz? tooltipContactEdit Kişi düzenle tooltipContactAdd Kişi ekle cleanHistory Geçmişi sil CreateAppSipAccount createAppSipAccountDescription Hesabınızı nasıl oluşturmak istersiniz? createAppSipAccountTitle %1 HESABI OLUŞTUR withPhoneNumber TELEFON NUMARASIYLA withEmailAddress E-POSTA ADRESİYLE CreateAppSipAccountWithEmail createAppSipAccountTitle %1 HESABI OLUŞTUR confirmAction OLUŞTUR usernameLabel Kullanıcı adı emailLabel E-posta passwordLabel Parola passwordConfirmationLabel Parola onayı passwordConfirmationError Girdiğiniz parolalar eşleşmiyor. quitWarning Hesabınız oluşturuldu ancak henüz doğrulanmadı. Bu görünümden çıkmak istediğinize emin misiniz? displayNameLabel Görünen ad (isteğe bağlı) CreateAppSipAccountWithPhoneNumber createAppSipAccountTitle %1 HESABI OLUŞTUR countryLabel Ülke phoneNumberLabel Telefon numarası usernameLabel Kullanıcı adı displayNameLabel Görünen ad (isteğe bağlı) confirmAction OLUŞTUR quitWarning Hesabınız oluşturuldu ancak henüz doğrulanmadı. Eğer bu görünümden çıkarsanız, hesabınızı 24 saat içinde doğrulamanız ve kendi kendinize yeniden eklemek zorunda kalırsınız. DroppableTextArea fileChooserTitle Lütfen bir veya daha çok dosya seçin dropYourAttachment Ekinizi atın attachmentTooltip Dosya gönder Event incomingCall Gelen çağrı outgoingCall Giden çağrı declinedIncomingCall Reddilen gelen çağrı declinedOutgoingCall Reddedilen giden çağrı endedCall Son verilen çağrı missedIncomingCall Yanıtsız gelen çağrı missedOutgoingCall Yanıtsız giden çağrı FetchRemoteConfiguration confirmAction AL fetchRemoteConfigurationTitle UZAKTAN YAPILANDIRMA AL urlLabel URL remoteProvisioningError Bu uzaktan ön hazırlık uri'si belirlenemiyor. remoteProvisioningUpdateDescription Uygulamanın yeniden başlaması gerekiyor. Şimdi yeniden başlatmak ister misiniz? HistoryView removeAllEntriesDescription Bu geçmişi temizlemek istediğinize emin misiniz? tooltipContactEdit Kişi düzenle tooltipContactAdd Kişi ekle cleanHistory Geçmişi sil Home howToDescription %1'un nasıl kullanılacağıyla ilgili yardıma mı gereksiniyorsunuz? howToTitle %1 NASIL KULLANILIR inviteDescription %1'daki arkadaşlarınızı davet edin. inviteTitle ARKADAŞLARINIZI DAVET EDİN accountAssistantDescription %1 hesabı oluştur veya yönet. accountAssistantTitle HESAP YARDIMCISI assistantButton YARDIMCI showTooltips Bilgi çubuklarını göster inviteButton DAVET ET Incall acceptVideoDescription Kişiniz görüntüyü açmak istiyor. pendingRequestLabel Lütfen bekleyin, bir istek askıda. securedStringFormat Çağrı şununla şifrelendi: %1. callNotSecured Çağrı şifrelenmedi. takeSnapshotLabel Anlık görüntü al. startRecordingLabel Kayda başla. stopRecordingLabel Kaydı durdur. IncallFullscreenWindow takeSnapshotLabel Anlık görüntü al. startRecordingLabel Kayda başla. stopRecordingLabel Kaydı durdur. InviteFriends enterEmailLabel Arkadaşın e-posta adresi messageLabel İleti cancel İPTAL confirm ONAYLA inviteFriendsTitle Arkadaşları Davet Et defaultMessage %1 sizi %2'da davet ediyor ! defaultSubject %1 daveti forcedMessage Uygulamayı bilgisayarınıza indirin ve kullanıcıları ücretsiz olarak aramaya ve konuşmaya başlayın. Buraya tıklayın: <a href="%1">%1</a> MainWindow mainSearchBarPlaceholder Kişi ara, çağrı veya sohbet başlat... homeEntry EV contactsEntry KİŞİLER autoAnswerStatus kendiliğinden smartSearchBarTooltip Sesli veya görüntülü çağrı başlatmak, ileti göndermek ve kişi eklemek için akıllı arama çubuğunu kullanın. Yalnızca arkadaşınızın SIP adresini veya kullanıcı adını girin. newConferenceButton Konferans aramasını başlat MainWindowMenuBar settings Tercihler about Hakkında quit Çıkış MainWindowTopMenuBar settings Tercihler about Hakkında quit Bırakın ManageAccounts ok TAMAM selectPresenceLabel Bulunma durumu selectAccountLabel Etkin hesap Message menuCopy Kopyala menuPlayMe Beni oynat! MultimediaParameters ok TAMAM Notifier newVersionAvailable Yeni sürüm (%1) var! newFileMessage Yeni ek alındı! OnlineInstallerDialog confirm ONAYLA onlineInstallerExtractingDescription %1 çıkarılıyor... onlineInstallerDownloadingDescription %1 indiriliyor... onlineInstallerFinishedDescription %1 kuruldu! onlineInstallerFailedDescription %1 kurulumu başarısız! OutgoingMessage messageError Hata messageRead Okundu messageDelivered İletildi Presence presenceOnline Uygun presenceBusy Meşgul presenceDoNotDisturb Rahatsız etme presenceOffline Çevrim dışı SettingsAdvanced logsTitle Günlükler logsFolderLabel Günlük klasörü sendLogs GÜNLÜKLERİ GÖNDER logsUploadUrlLabel Günlüklerin yükleneceği sunucu url'si logsUploadFailed Günlük yükleme başarısız. logsEnabledLabel Günlükler etkin cleanLogs GÜNLÜKLERİ TEMİZLE cleanLogsDescription Tüm günlükleri temizlemek istediğinize emin misiniz? developerSettingsTitle Geliştirici ayarları developerSettingsEnabledLabel Geliştirici ayarlarını etkinleştir logsMailerFailed Message when Linphone try to open a mailer to send logs, after uploading them to the server (%1 would be the upload url) Posta bulunamadı, ancak %1 konumuna günlükler yüklendi logsMailerSuccess Günlükler %1 dosyasına yüklendi SettingsAudio audioTitle Ses parametreleri playbackDeviceLabel Kayıttan oynatma aygıtı captureDeviceLabel Yakalama aygıtı ringerDeviceLabel Zil aygıtı ringLabel Zil echoCancellationLabel Yankı gidermeyi etkinleştir audioCodecsTitle Ses çözücüler showAudioCodecsLabel Ses çözücüleri göster playbackGainLabel Oynatma kazancı captureGainLabel Kazancı yakalayın audioTestLabel Yakalama seviyesi audioSettingsInCallWarning Sesli çağrı devam ediyor: bazı ayarlar kullanılamıyor. SettingsCallsChat fileServerLabel Dosya sunucusu encryptWithLimeLabel LIME ile şifrele limeDisabled Devre dışı limeRequired Zorunlu limePreferred Yeğlenen chatTitle Sohbet callsTitle Çağrılar encryptionLabel Şfireleme noEncryption Hiçbiri autoAnswerLabel Kendiliğinden yanıtla autoAnswerDelayLabel Gecikme (ms türünde) autoAnswerWithVideoLabel Kendiliğinden yanıtla (görüntüyle) chatEnabledLabel Konuşmayı etkinleştir callRecorderEnabledLabel Çağrı kaydediciyi etkinleştir chatNotificationSoundEnabledLabel Bildirim sesini etkinleştir chatNotificationSoundLabel Bildirim sesi conferenceEnabledLabel Toplantıyı etkinleştir contactsTitle Kişiler contactsEnabledLabel Kişileri etkinleştir muteMicrophoneEnabledLabel Mikrofonu kısmayı etkinleştir outgoingCallsEnabledLabel Giden çağrıları ektinleştir showTelKeypadAutomaticallyLabel Telefon numara takımını kendiliğinden göster automaticallyRecordCallsLabel Çağrıları kendiliğinden kaydet keepCallsWindowInBackgroundLabel Çağrı pencerelerini arka planda tut callPauseEnabledLabel Çağrı duraklatma etkin encryptionMandatoryLabel Şifreleme zorunludur SettingsNetwork sendDtmfsLabel DTMF'leri gönderme yöntemi allowIpV6Label IPv6'ya izin ver transportTitle Taşıma natAndFirewallTitle NAT ve Güvenlik Duvarı enableIceLabel ICE'yi etkinleştir stunServerLabel STUN/TURN sunucusu enableTurnLabel TURN'u etkinleştir turnUserLabel TURN kullanıcısı turnPasswordLabel TURN parolası networkProtocolAndPortsTitle Ağ iletişim kuralları ve bağlantı noktaları sipUdpPortLabel SIP UDP bağlantı noktası sipTcpPortLabel SIP TCP bağlantı noktası audioRtpUdpPortLabel Ses RTP UDP bağlantı noktası videoRtpUdpPortLabel Görüntü RTP UDP bağlantı noktası dscpFieldsTitle DSCP Alanları sipFieldLabel SIP audioRtpStreamFieldLabel Ses RTP Akışı videoRtpStreamFieldLabel Görüntü RTP Akışı bandwidthControlTitle Bant Genişliği Denetimi downloadSpeedLimitLabel Kbit/sn türünde indirme hız sınırı uploadSpeedLimitLabel Kbit/sn türünde yükleme hız sınırı enableAdaptiveRateControlLabel Uyarlanır oran denetimini etkinleştir presenceTitle Bulunma rlsUriLabel RLS URI'si kullan rlsUriAuto KENDİLİĞİNDEN rlsUriDisabled ASLA showNetworkSettingsLabel Ağ ayarlarını göster generalTitle Genel SettingsSipAccounts defaultIdentityTitle Öntanımlı kimlik defaultUsernameLabel Kullanıcı adı defaultSipAddressLabel SIP adresi proxyAccountsTitle Vekil hesapları eraseAllPasswords PAROLALARI SİL addAccount HESAP EKLE editHeader Düzenle deleteHeader Sil deleteAccountDescription Bu hesabı silmek istediğinize emin misiniz? eraseAllPasswordsDescription Tüm parolaları silmek istediğinize emin misiniz? defaultDisplayNameLabel Görünen ad assistantTitle Yardimci createAppSipAccountEnabledLabel Hesap oluşturmayı etkinleştir useAppSipAccountEnabledLabel Hesap kullanımını etkinleştir useOtherSipAccountEnabledLabel Genel hesap kullanımını etkinleştir fetchRemoteConfigurationEnabledLabel Yapılandırma almayı etkinleştir assistantSupportsPhoneNumbersLabel Telefon numaralarını destekler SettingsSipAccountsEdit sipAddressLabel SIP adresi transportLabel Taşıma serverAddressLabel SIP Sunucu adresi registrationDurationLabel Kaydolma uzunluğu (saniye) routeLabel Rota contactParamsLabel Kişi parametreleri publishPresenceLabel Bulunma bilgisini yayımla avpfIntervalLabel AVPF düzenli RTCP aralığı (saniye) registerEnabledLabel Kaydol avpfEnabledLabel AVPF'yi etkinleştir cancel İPTAL confirm ONAYLA invalidSipAddress Geçersiz SIP adresi. invalidServerAddress Geçersiz sunucu adresi. invalidRoute Geçersiz rota. enableIceLabel ICE'yi etkinleştir stunServerLabel STUN/TURN sunucusu enableTurnLabel TURN'u etkinleştir turnUserLabel TURN kullanıcısı turnPasswordLabel TURN parolası natAndFirewallTitle NAT ve Güvenlik Duvarı mainSipAccountSettingsTitle Ana SIP hesabı ayarları SettingsUi pathsTitle Yollar savedScreenshotsLabel Kaydedilen ekran görüntüleri klasörü savedCallsLabel Kaydedilen çağrılar klasörü languagesTitle Diller languagesLabel Dil systemLocale Sistem yereli cleanAvatars AVATARLARI SİL cleanAvatarsDescription Tüm avatarları silmek istediğinize emin misiniz? downloadLabel İndirme klasörü setLocaleDescription Uygulamanın yeniden başlaması gerekiyor. Şimdi yeniden başlatmak ister misiniz? otherTitle Diğer exitOnCloseLabel Pencere kapatıldığında uygulamadan çık dataTitle Kullanıcı Arayüzü Verisi autoStartLabel Uygulamayı kendiliğinden başlat SettingsVideo videoInputDeviceLabel Görüntü giriş aygıtı videoFramerateLabel Çerçeve oranı videoCaptureTitle Görüntü yakalama parametreleri videoPresetLabel Görüntü ön ayarı presetDefault Öntanımlı presetHighFps Yüksek saniye başına çerçeve presetCustom Özel videoSizeLabel Görüntü çözünürlüğü videoCodecsTitle Görüntü çözücüler showCameraPreview GÖRÜNTÜ ÖNİZLEMESİ showVideoCodecsLabel Görüntü çözücüleri göster videoSettingsInCallWarning Görüntülü arama devam ediyor: bazı ayarlar mevcut değil. SettingsVideoPreview confirm TAMAM SettingsWindow settingsTitle Ayarlar sipAccountsTab SIP hesapları audioTab Ses videoTab Görüntü callsAndChatTab Çağrı ve Sohbet networkTab uiTab Kullanıcı Arayüzü validButton TAMAM uiAdvanced Gelişmiş SmartSearchBar addContact KİŞİ EKLE Timeline timelineTitle Önceden UseAppSipAccount confirmAction KULLAN useAppSipAccountTitle %1 HESABI KULLAN useUsernameToLogin Telefon numaranız yerine kullanıcı adı ve parola kullanın. quitWarning Hesabınız oluşturuldu ancak henüz doğrulanmadı. Bu görünümden çıkmak istediğinize emin misiniz? UseAppSipAccountWithPhoneNumber countryLabel Ülke phoneNumberLabel Telefon numarası UseAppSipAccountWithUsername usernameLabel Kullanıcı adı passwordLabel Parola UseOtherSipAccount confirmAction KULLAN useOtherSipAccountTitle SIP HESABI KULLAN usernameLabel Kullanıcı adı displayNameLabel Görünen ad (isteğe bağlı) sipDomainLabel SIP Alan Adı passwordLabel Parola transportLabel Taşıma addOtherSipAccountError Bu hesap eklenemiyor. ZrtpTokenAuthentication confirmSas Aşağıdaki kısa yetkilendirme dizgesini eşinizle onaylayın. codeA Söyleyin: codeB Kişiniz şunu söylemeli: deny REDDET accept ONAYLA country Afghanistan Afganistan Albania Arnavutluk Algeria Cezayir AmericanSamoa Amerikan Samoası Andorra Andorra Angola Angola Anguilla Anguilla AntiguaAndBarbuda Antigua ve Barbuda Argentina Arjantin Armenia Ermenistan Aruba Aruba Australia Avustralya Austria Avusturya Azerbaijan Azerbaycan Bahamas Bahamalar Bahrain Bahreyn Bangladesh Bangladeş Barbados Barbados Belarus Belarus Belgium Belçika Belize Belize Benin Benin Bermuda Bermuda Bhutan Bhutan Bolivia Bolivya BosniaAndHerzegowina Bosna-Hersek Botswana Botsvana Brazil Brezilya Brunei Bruney Bulgaria Bulgaristan BurkinaFaso Burkina Faso Burundi Burundi Cambodia Kamboçya Cameroon Kamerun Canada Kanada CapeVerde Yeşil Burun Adaları CaymanIslands Cayman Adaları CentralAfricanRepublic Orta Afrika Cumhuriyeti Chad Çad Chile Şili China Çin Colombia Kolombiya Comoros Komorlar PeoplesRepublicOfCongo Kongo Cumhuriyeti DemocraticRepublicOfCongo Demokratik Kongo Cumhuriyeti CookIslands Cook Adaları CostaRica Kosta Rika IvoryCoast Fildişi Sahili Croatia Hırvatistan Cuba Küba Cyprus Kıbrıs CzechRepublic Çek Cumhuriyeti Denmark Danimarka Djibouti Cibuti Dominica Dominika DominicanRepublic Dominik Cumhuriyeti Ecuador Ekvador Egypt Mısır ElSalvador El Salvador EquatorialGuinea Ekvator Ginesi Eritrea Eritre Estonia Estonya Ethiopia Etyopya FalklandIslands Falkland Adaları FaroeIslands Faroe Adaları Fiji Fiji Finland Finlandiya France Fransa FrenchGuiana Fransız Guyanası FrenchPolynesia Fransız Polinezyası Gabon Gabon Gambia Gambiya Georgia Georgia Germany Almanya Ghana Gana Gibraltar Cebelitarık Greece Yunanistan Greenland Grönland Grenada Grenada Guadeloupe Guadeloupe Guam Guam'a Guatemala Guatemala Guinea Gine GuineaBissau Gine Bissau Guyana Guyana Haiti Haiti Honduras Honduras HongKong Hong Kong Hungary Macaristan Iceland İzlanda India Hindistan Indonesia Endonezya Iran İran Iraq Irak Ireland İrlanda Israel İsrail Italy İtalya Jamaica Jamaika Japan Japonya Jordan Ürdün Kazakhstan Kazakistan Kenya Kenya Kiribati Kiribati DemocraticRepublicOfKorea Kore Demokratik Cumhuriyeti RepublicOfKorea Kore Cumhuriyeti Kuwait Kuveyt Kyrgyzstan Kırgızistan Laos Laos Latvia Letonya Lebanon Lübnan Lesotho Lesotho Liberia Liberya Libya Libya Liechtenstein Lihtenştayn Lithuania Litvanya Luxembourg Lüksemburg Macau Makao Macedonia Makedonya Madagascar Madagaskar Malawi Malavi Malaysia Malezya Maldives Maldivler Mali Mali Malta Malta MarshallIslands Marshall Adaları Martinique Martinik Mauritania Moritanya Mauritius Mauritius Mayotte Mayotte Mexico Meksika Micronesia Mikronezya Moldova Moldova Monaco Monako Mongolia Moğolistan Montenegro Karadağ Montserrat Montserrat Morocco Fas Mozambique Mozambik Myanmar Myanmar Namibia Namibya NauruCountry Nauru Nepal Nepal Netherlands Hollanda NewCaledonia Yeni Kaledonya NewZealand Yeni Zelanda Nicaragua Nikaragua Niger Nijer Nigeria Nijerya Niue Niue NorfolkIsland Norfolk Adası NorthernMarianaIslands Kuzey Mariana Adaları Norway Norveç Oman Umman Pakistan Pakistan Palau Palau PalestinianTerritories Filistin Toprakları Panama Panama PapuaNewGuinea Papua Yeni Gine Paraguay Paraguay Peru Peru Philippines Filipinler Poland Polonya Portugal Portekiz PuertoRico Porto Riko Qatar Katar Reunion Buluşma Romania Romanya RussianFederation Rusya Federasyonu Rwanda Ruanda SaintHelena Saint Helena SaintKittsAndNevis Saint Kitts ve Nevis SaintLucia Saint Lucia SaintPierreAndMiquelon Saint Pierre ve Miquelon SaintVincentAndTheGrenadines Saint Vincent ve Grenadinler Samoa Samoa SanMarino San Marino SaoTomeAndPrincipe São Tomé ve Principe SaudiArabia Suudi Arabistan Senegal Senegal Serbia Sırbistan Seychelles Seyşeller SierraLeone Sierra Leone Singapore Singapur Slovakia Slovakya Slovenia Slovenya SolomonIslands Solomon Adaları Somalia Somali SouthAfrica Güney Afrika Cumhuriyeti Spain İspanya SriLanka Sri Lanka Sudan Sudan Suriname Surinam Swaziland Svaziland Sweden İsveç Switzerland İsviçre Syria Suriye Taiwan Tayvan Tajikistan Tacikistan Tanzania Tanzanya Thailand Tayland Togo Togo Tokelau Tokelau Tonga Tonga TrinidadAndTobago Trinidad ve Tobago Tunisia Tunus Turkey Türkiye Turkmenistan Türkmenistan TurksAndCaicosIslands Turks ve Caicos Adaları Tuvalu Tuvalu Uganda Uganda Ukraine Ukrayna UnitedArabEmirates Birleşik Arap Emirlikleri UnitedKingdom Birleşik Krallık UnitedStates Amerika Birleşik Devletleri Uruguay Uruguay Uzbekistan Özbekistan Vanuatu Vanuatu Venezuela Venezuela Vietnam Vietnam WallisAndFutunaIslands Wallis ve Futuna Adaları Yemen Yemen Zambia Zambiya Zimbabwe Zimbabve linphone-utils downloadCodecDescription %1 (%2) indirilmesini istiyor musunuz? linphone-desktop-4.2.5/linphone-app/assets/languages/uk.ts000066400000000000000000002672661376717241300236740ustar00rootroot00000000000000 About ok Так ActivateAppSipAccountWithEmail activateAppSipAccount АКТИВУЙТЕ ВАШУ ОБЛІКІВКУ %1 confirmAction АКТИВУВАТИ activationSteps Щоб активувати обліківку, дотримуйтесь дієвказів, котрі ми відіслали на %1, потім натисніть нижче. ActivateAppSipAccountWithPhoneNumber activateAppSipAccount АКТИВУЙТЕ ВАШУ ОБЛІКІВКУ %1 confirmAction АКТИВУВАТИ activationSteps Ми відправили SMS з кодом підтвердження на %1. Для завершення підтвердження вашого номера телефону, будь ласка, уведіть нижче 4-значний код. App commandLineOptionVerbose виводити в stdout декотру зневаджувальну інформацію під час роботи commandLineOptionConfig вкажіть конфігураційний файл %1 applicationDescription Вільний(безкоштовний) застосунок для SIP відео дзвінків. commandLineOptionIconified запускати згорнутою в ділянку сповіщень, не показувати основний інфтерфейс commandLineOptionConfigArg файл commandLineOptionHelp показати цю довідку commandLineOptionVersion показати версію застосунку commandLineOptionCliHelp показує меню допомоги у використанні %1 з командного рядка commandLineDescription відправка команди додатку через командний рядок restore Відновити quit Вийти settings Налаштування about Про AssistantAbstractView back НАЗАД AssistantHome useAppSipAccount ВИКОРИСТОВУВАТИ ОБЛІКІВКУ %1 useOtherSipAccount ВИКОРИСТОВУВАТИ SIP ОБЛІКІВКУ fetchRemoteConfiguration ЗАВАНТАЖИТИ ВІДДАЛЕНУ КОНФІГУРАЦІЮ homeTitle ЛАСКАВО ПРОСИМО homeDescription Цей асистент допоможе вам налаштувати та використовувати вашу обліківку %1. createAppSipAccount СТВОРИТИ ОБЛІКІВКУ %1 AssistantModel loginWithUsernameFailed Не вдалося увійти. Будь ласка, перевірте правильність уведення імени користувача та паролю. usernameStatusTooShort Закоротке! (щонайм. %1 символів) usernameStatusTooLong Задовге! (щонайб. %1 символів) usernameStatusInvalidCharacters Виявлено неприпустимі символи. (regex: `%1`) usernameStatusInvalid Неприпустиме ім'я користувача. passwordStatusTooShort Закороткий! (щонайм. %1 символів) passwordStatusTooLong Задовгий! (щонайб. %1 символів) passwordStatusInvalidCharacters Виявлено неприпустимі символи. (regex: `%1`) passwordStatusMissingCharacters Бракує символів: `%1`. requestFailed Не вдалося відправити запит. emailStatusMalformed Неприпустима адреса пошти. emailStatusMalformedInvalidCharacters Неприпустима адреса пошти або неприпустимі символи. cannotSendSms Помилка сервера: не вдалося надіслати SMS. accountAlreadyExists Така обліківка вже існує. smsActivationFailed SMS активація не вдалася! emailActivationFailed Будь ласка, переконайтеся в тому, що ви підтвердили вашу обліківку, або спробуйте знову. phoneNumberStatusInvalid Неприпустимий номер телефону! phoneNumberStatusTooShort Закороткий! phoneNumberStatusTooLong Задовгий! phoneNumberStatusInvalidCountryCode Неприпустимий код країни! loginWithPhoneNumberFailed Не вдалося увійти. Будь ласка перевірте правильність уведення номеру телефону. unableToAddAccount Не вдалося додати цю обліківку. AuthenticationRequest cancel СКАСУВАТИ confirm УВІЙТИ identityLabel Логін passwordLabel Пароль authenticationRequestDescription Не вдалося виконати розпізнання. Будь ласка, перевірте правильність уведення паролю. userIdLabel ID користувача (не обов'язково) realmLabel Область CallModel callStatsCodec Кодек callStatsUploadBandwidth Вихідна швидкість callStatsDownloadBandwidth Вхідна швидкість callStatsEstimatedDownloadBandwidth Передбачувана вхідна швидкість callStatsIceState Стан ICE callStatsIpFamily Родина IP callStatsSenderLossRate Втрати вихідних пакетів callStatsReceiverLossRate Втрати вхідних пакетів callStatsJitterBuffer Буфер коливань затримки callStatsSentVideoDefinition Роздільність вихідного відео callStatsReceivedVideoDefinition Роздільність вхідного відео iceStateNotActivated Не активовано iceStateFailed Невдало iceStateInProgress В процесі iceStateReflexiveConnection Рефлексивне з'єднання iceStateHostConnection Під'єднання хосту iceStateRelayConnection Релейне з'єднання iceStateInvalid Неприпустимо callErrorDeclined Віддалена сторона відхилила виклик. callErrorNotFound Віддалена сторона не знайдена. callErrorBusy Віддалена сторона зайнята. callErrorNotAcceptable Віддалена сторона не може прийняти виклик. callStatsReceivedFramerate Вхідна частота кадрів callStatsSentFramerate Вихідна частота кадрів CallSipAddress cancel СКАСУВАТИ callSipAddressDescription Почати новий виклик. CallStatistics audioStatsLabel Звук videoStatsLabel Відео CallTransfer cancel СКАСУВАТИ callTransferDescription Волієте переспрямувати цей виклик? Calls acceptAudioCall ПРИЙНЯТИ ЗВУКОВИЙ ВИКЛИК acceptVideoCall ПРИЙНЯТИ ВІДЕО ВИКЛИК terminateCall ЗАВЕРШИТИ ВИКЛИК resumeCall ПРОДОВЖИТИ ВИКЛИК transferCall ПЕРЕСПРЯМУВАТИ ВИКЛИК callPause ПРИЗУПИНИТИ ВИКЛИК CallsWindow callsTitle Дзвінки acceptClosingDescription Ви впевнені, що бажаєте завершити усі виклики? Chat newMessagePlaceholder Уведіть повідомлення noFileTransferUrl Не вдалося відіслати файл. Не налаштовано адресу сервера. isComposing %1 друкує... Cli appCliDescription Спосіб керувати %1 через командний рядок. uriCommandLineSyntax %1 sip:<адреса-sip>?method=<метод>([&<аргумент>=<base64-значення>]*) cliCommandLineSyntax %1 "<method> ([<argument>=<value>]*)" commandsName перелік команд: showFunctionDescription Показати головне вікно застосунку. callFunctionDescription Почати виклик SIP адреси. initiateConferenceFunctionDescription Почати конференцію. joinConferenceFunctionDescription Приєднайтеся до конференції за sip-адресою. Якщо ви під'єднані до конфігурації проксі, див. join-conference-as. joinConferenceAsFunctionDescription Приєднайтеся до конференції за sip-адресою. Якщо ви не під'єднані до конфігурації проксі, див. join-conference-as. CodecsViewer codecMime Назва codecEncoderDescription Опис codecEncoderClockRate Частота (Гц) codecBitrate Бітрейт (Кбіт/с) codecRecvFmtp Параметри codecStatus Статус Conference conferenceTitle КОНФЕРЕНЦІЯ ConferenceControls conference КОНФЕРЕНЦІЯ ConferenceManager conferenceManagerDescription Керуйте учасниками вашої конференції. cancel СКАСУВАТИ confirm ПОЧАТИ ConfirmDialog cancel СКАСУВАТИ confirm СХВАЛИТИ ContactEdit removeContactDescription Ви справді бажаєте вилучити цей контакт з вашої адресної книги? sipAccounts SIP ОБЛІКІВКА(И) address АДРЕСА emails E-MAIL webSites САЙТ(И) avatarChooserTitle Оберіть вашу мармизку companies КОМПАНІЇ save ЗБЕРЕГТИ cancel СКАСУВАТИ sipAccountsPlaceholder SIP обліківка companiesPlaceholder Компанія emailsPlaceholder Email webSitesPlaceholder Сайт street Вулиця postalCode Поштовий індекс country Країна locality Населений пункт abortEditDescriptionText Ви впевнені, що бажаєте скасувати зміну контакту? tooltipShowConversation Показати розмову Contacts searchContactPlaceholder Знайти контакт selectAllContacts Усі selectConnectedContacts Під'єднані addContact ДОДАТИ КОНТАКТ removeContactDescription Ви справді бажаєте вилучити цей контакт з вашої адресної книги? Conversation displayCallsAndMessages УСІ displayCalls ВИКЛИКИ displayMessages ПОВІДОМЛЕННЯ removeAllEntriesDescription Ви впевнені, що волієте вичистити цю історію? tooltipContactEdit Редагувати контакт tooltipContactAdd Додати контакт cleanHistory Вилучити історію CreateAppSipAccount createAppSipAccountDescription Як би ви воліли створити обліківку? createAppSipAccountTitle СТВОРИТИ ОБЛІКІВКУ %1 withPhoneNumber ЗА ДОПОМОГОЮ НОМЕРУ ТЕЛЕФОНУ withEmailAddress ЗА ДОПОМОГОЮ EMAIL CreateAppSipAccountWithEmail createAppSipAccountTitle СТВОРИТИ ОБЛІКІВКУ %1 confirmAction СТВОРИТИ usernameLabel Ім'я користувача emailLabel Email passwordLabel Пароль passwordConfirmationLabel Схвалення паролю passwordConfirmationError Уведені паролі не збігаються quitWarning Ваша обліківка була створена, але ще не підтверджена. Ви впевнені, що волієте вийти? displayNameLabel Показуване ім'я (не обов'язково) CreateAppSipAccountWithPhoneNumber createAppSipAccountTitle СТВОРИТИ ОБЛІКІВКУ %1 countryLabel Країна phoneNumberLabel Номер телефону usernameLabel Ім'я користувача displayNameLabel Показуване ім'я (не обов'язково) confirmAction СТВОРИТИ quitWarning Вашу обліківку було створено, але ще не підтверджено. Якщо ви вийдете, вам знадобиться вручну додати та підтвердити свою обліківку впродовж 24 годин. DroppableTextArea fileChooserTitle Будь ласка, оберіть один або декілька файлів. dropYourAttachment Помістіть вкладення attachmentTooltip Відіслати файл Event incomingCall Вхідний виклик outgoingCall Вихідний виклик declinedIncomingCall Відхилений вхідний виклик declinedOutgoingCall Відхилений вихідний виклик endedCall Закінчений виклик missedIncomingCall Пропущений вхідний виклик missedOutgoingCall Пропущений вихідний виклик FetchRemoteConfiguration confirmAction ЗАВАНТАЖИТИ fetchRemoteConfigurationTitle ЗАВАНТАЖИТИ ВІДДАЛЕНУ КОНФІГУРАЦІЮ urlLabel URL remoteProvisioningError Неможливо встановити це віддалене налаштування uri. remoteProvisioningUpdateDescription Потрібно перезапустити застосунок. Бажаєте перезапустити зараз? HistoryView removeAllEntriesDescription Ви впевнені, що волієте вичистити цю історію? tooltipContactEdit Редагувати контакт tooltipContactAdd Додати контакт cleanHistory Вилучити історію Home howToDescription Потрібна допомога у використанні %1? howToTitle ЯК КОРИСТУВАТИСЯ %1 inviteDescription Запросіть друзів використовувати %1. inviteTitle ЗАПРОСІТЬ ДРУЗІВ accountAssistantDescription Створення і керування обліківкою %1. accountAssistantTitle АСИСТЕНТ ОБЛІКІВКИ assistantButton АСИСТЕНТ showTooltips Показувати підказки inviteButton ЗАПРОСИТИ Incall acceptVideoDescription Ваш контакт волів би увімкнути відео. pendingRequestLabel Будь ласка, зачекайте, запит опрацьовується. securedStringFormat Виклик зашифрований з: %1. callNotSecured Виклик не зашифрований. takeSnapshotLabel Зробити зняток. startRecordingLabel Почати запис. stopRecordingLabel Зупинити запис. IncallFullscreenWindow takeSnapshotLabel Зробити зняток. startRecordingLabel Почати запис. stopRecordingLabel Зупинити запис. InviteFriends enterEmailLabel Email друга messageLabel Повідомлення cancel СКАСУВАТИ confirm СХВАЛИТИ inviteFriendsTitle Запросити друзів defaultMessage %1 запрошує вас використовувати %2 ! defaultSubject Запрошення %1 forcedMessage Завантажте застосунок на ваш комп'ютер та почніть телефонувати і спілкуватися безкоштовно Посилання для завантаження: <a href="%1">%1</a> MainWindow mainSearchBarPlaceholder Знайти контакт, почати дзвінок або чат… homeEntry ДОМІВКА contactsEntry КОНТАКТИ autoAnswerStatus авто smartSearchBarTooltip Використовуйте розумний пошуковий рядок, щоб одразу почати звуковий або відео виклик відіслати повідомлення чи додати новий контакт. Просто уведіть SIP адресу чи ім'я користувача вашого контакту. newConferenceButton Почати конференц-дзвінок MainWindowMenuBar settings Налаштування about Про quit Вийти MainWindowTopMenuBar settings Уподобання about Про це quit Кинути ManageAccounts ok Так selectPresenceLabel Статус selectAccountLabel Активна обліківка Message menuCopy Копіювати menuPlayMe Грай! MultimediaParameters ok Так Notifier newVersionAvailable Доступна нова (%1) версія! newFileMessage Отримано новий файл! OnlineInstallerDialog confirm ПІДТВЕРДИТИ onlineInstallerExtractingDescription Витягування %1… onlineInstallerDownloadingDescription Завантаження %1… onlineInstallerFinishedDescription %1 встановлено! onlineInstallerFailedDescription Не вдалося встановити %1! OutgoingMessage messageError Помилка messageRead Прочитано messageDelivered Доставлено Presence presenceOnline Доступний presenceBusy Зайнятий presenceDoNotDisturb Не бентежити presenceOffline Не в мережі SettingsAdvanced logsTitle Журнали logsFolderLabel Тека журналів sendLogs НАДСИЛАННЯ ЖУРНАЛІВ logsUploadUrlLabel URL сервера для надсилання журналів logsUploadFailed Не вдалося надіслати журнали logsEnabledLabel Журнали включені cleanLogs ВИЛУЧИТИ ЖУРНАЛИ cleanLogsDescription Ви впевнені, що волієте вилучити усі журнали? developerSettingsTitle Налаштування для розробників developerSettingsEnabledLabel Увімкнути налаштування для розробників logsMailerFailed Message when Linphone try to open a mailer to send logs, after uploading them to the server (%1 would be the upload url) Не вдалося знайти поштову програму, але журнали було вивантажено до %1 logsMailerSuccess Журнали було вивантажено до %1 SettingsAudio audioTitle Параметри звуку playbackDeviceLabel Пристрій відтворення captureDeviceLabel Пристрій захоплення ringerDeviceLabel Пристрій дзвінка ringLabel Дзвінок echoCancellationLabel Увімкнути пригнічення луни audioCodecsTitle Звукові кодеки showAudioCodecsLabel Показати звукові кодеки playbackGainLabel Посилення відтворення captureGainLabel Посилення захоплення audioTestLabel Рівень захоплення audioSettingsInCallWarning Прогрес аудіодзвінку: деякі настройки недоступні. SettingsCallsChat fileServerLabel Файловий сервер encryptWithLimeLabel Шифрувати за допомогою LIME limeDisabled Вимкнено limeRequired Обов'язково limePreferred Бажано chatTitle Чат callsTitle Дзвінки encryptionLabel Шифрування noEncryption Ні autoAnswerLabel Приймати виклик самочинно autoAnswerDelayLabel Затримка (в мс) autoAnswerWithVideoLabel Приймати виклик самочинно (з відео) chatEnabledLabel Увімкнути чат callRecorderEnabledLabel Увімкнути запис дзвінків chatNotificationSoundEnabledLabel Увімкнути звук сповіщень chatNotificationSoundLabel Звук сповіщень conferenceEnabledLabel Увімкнути конференцію contactsTitle Контакти contactsEnabledLabel Увімкнути контакти muteMicrophoneEnabledLabel Увімкнути звук мікрофону outgoingCallsEnabledLabel Увімкнення вихідних викликів showTelKeypadAutomaticallyLabel Показувати телефонну набірницю автоматично automaticallyRecordCallsLabel Автоматично записувати дзвінки keepCallsWindowInBackgroundLabel Підтримувати дзвінки у згорнутому режимі callPauseEnabledLabel Виклик призупинено encryptionMandatoryLabel Обов'язковий заселення SettingsNetwork sendDtmfsLabel Метод відправки DTMF allowIpV6Label Дозволити IPv6 transportTitle Транспорт natAndFirewallTitle NAT та файрвол enableIceLabel Увімкнути ICE stunServerLabel Сервер STUN/TURN enableTurnLabel Увімкнути TURN turnUserLabel Користувач TURN turnPasswordLabel Пароль TURN networkProtocolAndPortsTitle Мережевий протокол і порти sipUdpPortLabel UDP порт SIP sipTcpPortLabel TCP порт SIP audioRtpUdpPortLabel UDP порт RTP аудіо videoRtpUdpPortLabel UDP порт RTP відео dscpFieldsTitle Поля DSCP sipFieldLabel SIP audioRtpStreamFieldLabel Потік RTP аудіо videoRtpStreamFieldLabel Потік RTP відео bandwidthControlTitle Керування смугою пропускання downloadSpeedLimitLabel Обмежити вхідну швидкість до Кбіт/сек uploadSpeedLimitLabel Обмежити вихідну швидкість до Кбіт/сек enableAdaptiveRateControlLabel Увімкнути адаптивне керування швидкістю presenceTitle Статус rlsUriLabel Використовувати RLS URI rlsUriAuto АВТО rlsUriDisabled НІКОЛИ showNetworkSettingsLabel Показати мережеві налаштування generalTitle Основні SettingsSipAccounts defaultIdentityTitle Типове посвідчення defaultUsernameLabel Ім'я користувача defaultSipAddressLabel Адреса SIP proxyAccountsTitle Проксі обліківки eraseAllPasswords ВИЛУЧИТИ ПАРОЛІ addAccount ДОДАТИ ОБЛІКІВКУ editHeader Змінити deleteHeader Вилучити deleteAccountDescription Ви впевнені, що бажаєте вилучити цю обліківку? eraseAllPasswordsDescription Ви впевнені, що бажаєте вилучити усі паролі? defaultDisplayNameLabel Показуване ім'я assistantTitle Помічник createAppSipAccountEnabledLabel Увімкнути створення обліківки useAppSipAccountEnabledLabel Увімкнути використання обліківки useOtherSipAccountEnabledLabel Увімкнути використання спільної обліківки fetchRemoteConfigurationEnabledLabel Увімкнути вибір конфігурації assistantSupportsPhoneNumbersLabel Підтримує номери телефонів SettingsSipAccountsEdit sipAddressLabel Адреса SIP transportLabel Транспорт serverAddressLabel Адреса сервера SIP registrationDurationLabel Тривалість реєстрації (сек) routeLabel Маршрут contactParamsLabel Контактні параметри publishPresenceLabel Оголошувати статус avpfIntervalLabel AVPF звичайний RTCP інтервал (сек) registerEnabledLabel Реєстрація avpfEnabledLabel Увімкнути AVPF cancel СКАСУВАТИ confirm ПІДТВЕРДИТИ invalidSipAddress Неприпустима SIP адреса. invalidServerAddress Неприпустима адреса сервера. invalidRoute Неправильний маршрут. enableIceLabel Увімкнути ICE stunServerLabel Сервер STUN/TURN enableTurnLabel Увімкнути TURN turnUserLabel Користувач TURN turnPasswordLabel Пароль TURN natAndFirewallTitle NAT і файрвол mainSipAccountSettingsTitle Основні налаштування SIP обліківки SettingsUi pathsTitle Шляхи savedScreenshotsLabel Тека для збереження знятків savedCallsLabel Тека для запису дзвінків languagesTitle Мови languagesLabel Мова systemLocale Системна cleanAvatars ВИЛУЧИТИ МАРМИЗКИ cleanAvatarsDescription Ви впевнені, що волієте вилучити усі мармизки? downloadLabel Тека завантажень setLocaleDescription Необхідний перезапуск програми. Бажаєте перезапустити зараз? otherTitle Инше exitOnCloseLabel Завершувати програму при закритті вікна dataTitle Дані користувацького інтерфейсу autoStartLabel Самозапуск SettingsVideo videoInputDeviceLabel Пристрій-джерело відео videoFramerateLabel Частота кадрів videoCaptureTitle Параметри захоплення відео videoPresetLabel Пресет відео presetDefault Типово presetHighFps Висока частота кадрів presetCustom Користувацьке videoSizeLabel Роздільність відео videoCodecsTitle Відео кодеки showCameraPreview ПОПЕРЕГЛЯД ВІДЕО showVideoCodecsLabel Показати Відео кодеки videoSettingsInCallWarning Відеодзвінок в процесі: деякі настройки недоступні. SettingsVideoPreview confirm Так SettingsWindow settingsTitle Налаштування sipAccountsTab SIP обліківки audioTab Звук videoTab Відео callsAndChatTab Дзвінки і чат networkTab Мережа uiTab Інтерфейс validButton Так uiAdvanced Додаткове SmartSearchBar addContact ДОДАТИ КОНТАКТ Timeline timelineTitle Заздалегідь UseAppSipAccount confirmAction ВИКОРИСТОВУВАТИ useAppSipAccountTitle ВИКОРИСТОВУВАТИ ОБЛІКІВКУ %1 useUsernameToLogin Використовувати ім'я користувача та пароль замість номеру телефону. quitWarning Вашу обліківку було створено, але ще не підтверджено. Ви впевнені, що бажаєте вийти? UseAppSipAccountWithPhoneNumber countryLabel Країна phoneNumberLabel Номер телефону UseAppSipAccountWithUsername usernameLabel Ім'я користувача passwordLabel Пароль UseOtherSipAccount confirmAction ВИКОРИСТОВУВАТИ useOtherSipAccountTitle ВИКОРИСТОВУВАТИ SIP ОБЛІКІВКУ usernameLabel Ім'я користувача displayNameLabel Показуване ім'я (не обов'язково) sipDomainLabel Домен SIP passwordLabel Пароль transportLabel Транспорт addOtherSipAccountError Не вдалося додати цю обліківку. ZrtpTokenAuthentication confirmSas Підтвердіть такий рядок автентифікації з контактом. codeA Скажіть: codeB Ваш контакт повинен сказати: deny ВІДХИЛИТИ accept СХВАЛИТИ country Afghanistan Афганістан Albania Албанія Algeria Алжір AmericanSamoa Американське Самоа Andorra Андорра Angola Анґола Anguilla Анґілья AntiguaAndBarbuda Антиґуа і Барбуда Argentina Арґентина Armenia Вірменія Aruba Аруба Australia Австралія Austria Австрія Azerbaijan Азербайджан Bahamas Багами Bahrain Бахрейн Bangladesh Банґладеш Barbados Барбадос Belarus Білорусь Belgium Бельґія Belize Беліз Benin Бенін Bermuda Бермудські Острови Bhutan Бутан Bolivia Болівія BosniaAndHerzegowina Боснія і Герцеґовина Botswana Ботсвана Brazil Бразилія Brunei Бруней Bulgaria Болґарія BurkinaFaso Буркіна-Фасо Burundi Бурунді Cambodia Камбоджа Cameroon Камерун Canada Канада CapeVerde Кабо-Верде CaymanIslands Кайманові острови CentralAfricanRepublic Центральноафриканська Республіка Chad Чад Chile Чилі China Китай Colombia Колумбія Comoros Коморські острови PeoplesRepublicOfCongo Народна Республіка Конґо DemocraticRepublicOfCongo Демократична Республіка Конґо CookIslands Острови Кука CostaRica Коста-Ріка IvoryCoast Кот-д'Івуар Croatia Хорватія Cuba Куба Cyprus Кіпр CzechRepublic Чеська Республіка Denmark Данія Djibouti Джибуті Dominica Домініка DominicanRepublic Домініканська республіка Ecuador Еквадор Egypt Єгипет ElSalvador Сальвадор EquatorialGuinea Екваторіальна Ґвінея Eritrea Еритрея Estonia Естонія Ethiopia Ефіопія FalklandIslands Фолклендські (Мальвінські) острови FaroeIslands Фарерські острови Fiji Фіджі Finland Фінляндія France Франція FrenchGuiana Французька Ґвіана FrenchPolynesia Французька Полінезія Gabon Ґабон Gambia Ґамбія Georgia Грузія Germany Німеччина Ghana Гана Gibraltar Ґібралтар Greece Греція Greenland Ґренландія Grenada Ґренада Guadeloupe Ґваделупа Guam Ґуам Guatemala Ґватемала Guinea Ґвінея GuineaBissau Ґвінея-Бісау Guyana Ґайана Haiti Гаїті Honduras Гондурас HongKong Гонконґ Hungary Угорщина Iceland Ісландія India Індія Indonesia Індонезія Iran Іран Iraq Ірак Ireland Ірландія Israel Ізраїль Italy Італія Jamaica Ямайка Japan Японія Jordan Йорданія Kazakhstan Казахстан Kenya Кенія Kiribati Кірібаті DemocraticRepublicOfKorea Демократична Республіка Корея RepublicOfKorea Республіка Корея Kuwait Кувейт Kyrgyzstan Кирґизстан Laos Лаос Latvia Латвія Lebanon Ліван Lesotho Лесото Liberia Ліберія Libya Лівія Liechtenstein Ліхтенштейн Lithuania Литва Luxembourg Люксембурґ Macau Макао Macedonia Македонія Madagascar Мадаґаскар Malawi Малаві Malaysia Малайзія Maldives Мальдіви Mali Малі Malta Мальта MarshallIslands Маршаллові острови Martinique Мартініка Mauritania Мавританія Mauritius Маврикій Mayotte Майотта Mexico Мексика Micronesia Мікронезія Moldova Молдова Monaco Монако Mongolia Монґолія Montenegro Монтенеґро Montserrat Монтсеррат Morocco Марокко Mozambique Мозамбік Myanmar М'янма Namibia Намібія NauruCountry Науру Nepal Непал Netherlands Нідерланди NewCaledonia Нова Каледонія NewZealand Нова Зеландія Nicaragua Нікараґуа Niger Ніґер Nigeria Нігерія Niue Ніуе NorfolkIsland Острів Норфолк NorthernMarianaIslands Північні Маріанські острови Norway Норвегія Oman Оман Pakistan Пакістан Palau Палау PalestinianTerritories Палестинські території Panama Панама PapuaNewGuinea Папуа Нова Ґвінея Paraguay Параґвай Peru Перу Philippines Філіппіни Poland Польща Portugal Портуґалія PuertoRico Пуерто-Ріко Qatar Катар Reunion Реюньйон Romania Румунія RussianFederation Російська Федерація Rwanda Руанда SaintHelena Острів Св. Олени SaintKittsAndNevis Сент-Кітс і Невіс SaintLucia Сент-Люсія SaintPierreAndMiquelon Сен-П'єр і Мікелон SaintVincentAndTheGrenadines Сент-Вінсент і Ґренадіни Samoa Самоа SanMarino Сан-Маріно SaoTomeAndPrincipe Сан-Томе і Прінсіпі SaudiArabia Саудівська Аравія Senegal Сенеґал Serbia Сербія Seychelles Сейшельські острови SierraLeone Сьєрра-Леоне Singapore Сінґапур Slovakia Словаччина Slovenia Словенія SolomonIslands Соломонові острови Somalia Сомалі SouthAfrica Південна Африка Spain Еспанія SriLanka Шрі-Ланка Sudan Судан Suriname Сурінам Swaziland Свазіленд Sweden Швеція Switzerland Швейцарія Syria Сирія Taiwan Тайвань Tajikistan Таджикистан Tanzania Танзанія Thailand Таїланд Togo Тоґо Tokelau Токелау Tonga Тонґа TrinidadAndTobago Тринідад і Тобаґо Tunisia Туніс Turkey Турція Turkmenistan Туркменістан TurksAndCaicosIslands Острови Теркс і Кайкос Tuvalu Тувалу Uganda Уґанда Ukraine Україна UnitedArabEmirates Об'єднані Арабські Емірати UnitedKingdom Сполучене Королівство UnitedStates Сполучені Штати Uruguay Уруґвай Uzbekistan Узбекистан Vanuatu Вануату Venezuela Венесуела Vietnam В'єтнам WallisAndFutunaIslands Уолліс і Футуна Yemen Ємен Zambia Замбія Zimbabwe Зімбабве linphone-utils downloadCodecDescription Бажаєте завантажити %1 (%2)? linphone-desktop-4.2.5/linphone-app/assets/languages/zh_CN.ts000066400000000000000000002407321376717241300242430ustar00rootroot00000000000000 About ok ActivateAppSipAccountWithEmail activateAppSipAccount 激活你的 %1 账户 confirmAction 激活 activationSteps 按照我们发往 %1 的指示来激活账户,然后点击下面 ActivateAppSipAccountWithPhoneNumber activateAppSipAccount 激活你的 %1 账户 confirmAction 激活 activationSteps 我们发送了一条短信至 %1 ,要完成手机号码验证,请输入短信中的 4 位验证码 App commandLineOptionVerbose 在运行时向 stdout 输出调试日志 commandLineOptionConfig 指定要使用的配置文件:%1 applicationDescription 一个免费(且自由)的 SIP 网络电话 commandLineOptionIconified 启动时最小化到系统托盘,不显示主界面 commandLineOptionConfigArg 文件 commandLineOptionHelp 显示关于这个的帮助 commandLineOptionVersion 显示应用版本 commandLineOptionCliHelp 用 CLI 来显示使用 %1 的帮助菜单 commandLineDescription 向命令行中发送给应用程序的指令 restore 恢复 quit 退出 settings 偏好设置 about 关于 AssistantAbstractView back 返回 AssistantHome useAppSipAccount 使用 %1 账户 useOtherSipAccount 使用一个 SIP 账户 fetchRemoteConfiguration 获取远程配置文件 homeTitle 欢迎 homeDescription 该助手会帮助你配置并使用你的 SIP 账户 createAppSipAccount 创建一个 %1 账户 AssistantModel loginWithUsernameFailed 登录失败,请检查你的用户名/密码 usernameStatusTooShort 太短了!(最少需要 %1 个字符) usernameStatusTooLong 太长了!(最长 %1 个字符) usernameStatusInvalidCharacters 检测到无效字符。(regex: `%1`) usernameStatusInvalid 无效的用户名 passwordStatusTooShort 太短了!(最少 %1 个字符) passwordStatusTooLong 太长了!(最长 %1 个字符) passwordStatusInvalidCharacters 检测到无效字符。(regex: `%1`) passwordStatusMissingCharacters 缺少字符:`%1` 。 requestFailed 无法发送请求 emailStatusMalformed 邮箱地址错误 emailStatusMalformedInvalidCharacters 邮箱地址错误或检测到无效字符 cannotSendSms 服务器错误:无法发送短信 accountAlreadyExists 这个账户已存在 smsActivationFailed 短信激活失败! emailActivationFailed 请确保您已经验证了您的账户或重试 phoneNumberStatusInvalid 无效的手机号码! phoneNumberStatusTooShort 太短了! phoneNumberStatusTooLong 太长了! phoneNumberStatusInvalidCountryCode 无效的国家号码 loginWithPhoneNumberFailed 登录失败,请检查你的手机号码 unableToAddAccount 无法添加此账户 AuthenticationRequest cancel 取消 confirm 登录 identityLabel 身份 passwordLabel 密码 authenticationRequestDescription 无法验证,请检查你的密码 userIdLabel 用户 ID (可选) realmLabel 领域 CallModel callStatsCodec 编码解码器 callStatsUploadBandwidth 上传带宽 callStatsDownloadBandwidth 下载带宽 callStatsEstimatedDownloadBandwidth 预估下载带宽 callStatsIceState ICE 状态 callStatsIpFamily IP family callStatsSenderLossRate 发送者丢包率 callStatsReceiverLossRate 接收者丢包率 callStatsJitterBuffer 抖动缓冲器 callStatsSentVideoDefinition 发送的视频分辨率 callStatsReceivedVideoDefinition 接收的视频分辨率 iceStateNotActivated 未激活 iceStateFailed 失败 iceStateInProgress 进行中 iceStateReflexiveConnection 反射连接 iceStateHostConnection 主机连接 iceStateRelayConnection 中继连接 iceStateInvalid 无效 callErrorDeclined 对方拒绝了通话 callErrorNotFound 未找到对方 callErrorBusy 对方处于忙碌状态 callErrorNotAcceptable 对方无法接通 callStatsReceivedFramerate 接收的帧率 callStatsSentFramerate 发送的帧率 CallSipAddress cancel 取消 callSipAddressDescription 开始新的通话 CallStatistics audioStatsLabel 语音 videoStatsLabel 视频 CallTransfer cancel 取消 callTransferDescription 你想要转移当前通话吗? Calls acceptAudioCall 接受语音通话 acceptVideoCall 接受视频通话 terminateCall 挂断 resumeCall 继续通话 transferCall 转移通话 callPause 暂挂通话 CallsWindow callsTitle 通话 acceptClosingDescription 你确定要中止所有通话吗? Chat newMessagePlaceholder 输入你的消息 noFileTransferUrl 无法发送文件。 未配置服务器地址。 isComposing %1 正在输入 Cli appCliDescription 使用命令行工具控制 %1 应用的方法 uriCommandLineSyntax %1 <sip-address>?method=<method>([&<argument>=<base64-value>]*) cliCommandLineSyntax %1 "<method> ([<argument>=<value>]*)" commandsName 命令列表: showFunctionDescription 显示应用程序的主窗口 callFunctionDescription 向这个 SIP 地址拨号 initiateConferenceFunctionDescription 开始一个会议 joinConferenceFunctionDescription 以显示的名字加入由此 SIP 地址创建的会议。如果你连接到了代理,请参阅“以身份加入会议”。 joinConferenceAsFunctionDescription 以访客身份加入此 SIP 地址创建的会议。如果你未连接到代理,请参阅“加入会议” CodecsViewer codecMime 名字 codecEncoderDescription 描述信息 codecEncoderClockRate 率(赫兹) codecBitrate 比特率(Kbit/s) codecRecvFmtp 参数 codecStatus 状态 Conference conferenceTitle 会议 ConferenceControls conference 会议 ConferenceManager conferenceManagerDescription 管理会议参与者 cancel 取消 confirm 开始 ConfirmDialog cancel 取消 confirm 确定 ContactEdit removeContactDescription 你真的要从地址簿中移除该联系人吗? sipAccounts SIP 账户(可有多个) address 地址 emails 电子邮箱(可有多个) webSites 网站(可有多个) avatarChooserTitle 选择你的头像 companies 公司 save 保存 cancel 取消 sipAccountsPlaceholder SIP 账户 companiesPlaceholder 公司 emailsPlaceholder 电子邮箱 webSitesPlaceholder 网站 street 街道 postalCode 邮政编码 country 国家 locality 地区 abortEditDescriptionText 你确定要取消对联系人的更改吗? tooltipShowConversation 显示对话 Contacts searchContactPlaceholder 搜索联系人 selectAllContacts 全部 selectConnectedContacts 已连接 addContact 添加联系人 removeContactDescription 你真的要从地址簿中移除该联系人吗? Conversation displayCallsAndMessages 全部 displayCalls 通话 displayMessages 信息 removeAllEntriesDescription 你确定要清除该历史吗? tooltipContactEdit 编辑联系人 tooltipContactAdd 添加联系人 cleanHistory 删除历史记录 CreateAppSipAccount createAppSipAccountDescription 您想要如何创建账户? createAppSipAccountTitle 创建一个 %1 账户 withPhoneNumber 用手机号码 withEmailAddress 用电子邮箱地址 CreateAppSipAccountWithEmail createAppSipAccountTitle 创建一个 %1 账号 confirmAction 创建 usernameLabel 用户名 emailLabel 电子邮箱 passwordLabel 密码 passwordConfirmationLabel 再次输入密码 passwordConfirmationError 两次输入的密码不一致 quitWarning 您的账户已创建,但未验证。你确定要退出当前界面吗? displayNameLabel 显示名字(可选) CreateAppSipAccountWithPhoneNumber createAppSipAccountTitle 创建一个 %1 账户 countryLabel 国家 phoneNumberLabel 手机号码 usernameLabel 用户名 displayNameLabel 显示名字(可选) confirmAction 创建 quitWarning 您的账户已创建,但未验证。如果您退出当前界面,您将需要在 24 小时之内手动添加并验证您的账户。 DroppableTextArea fileChooserTitle 请选择一个或多个文件 dropYourAttachment 拖放您的附件 attachmentTooltip 发送文件 Event incomingCall 来电 outgoingCall 去电 declinedIncomingCall 已挂断来电 declinedOutgoingCall 已挂断去电 endedCall 已中止通话 missedIncomingCall 未接来电 missedOutgoingCall 未接去电 FetchRemoteConfiguration confirmAction 获取 fetchRemoteConfigurationTitle 获取远程配置文件 urlLabel 链接 remoteProvisioningError 无法设定该远程服务地址 remoteProvisioningUpdateDescription 需要重启应用程序。您想要立刻重启吗? HistoryView removeAllEntriesDescription 你确定要清除该历史吗? tooltipContactEdit 编辑联系人 tooltipContactAdd 添加联系人 cleanHistory 删除历史记录 Home howToDescription 需要关于如何使用 %1 的帮助? howToTitle 如何使用 %1 inviteDescription 在 %1 上邀请您的朋友 inviteTitle 邀请您的朋友 accountAssistantDescription 创建或管理您的 %1 账户 accountAssistantTitle 账户助手 assistantButton 助手 showTooltips 显示工具提示 inviteButton 邀请 Incall acceptVideoDescription 你的联系人希望开启视频通话 pendingRequestLabel 请稍候,请求等待中 securedStringFormat 通话使用 %1 加密 callNotSecured 通话未加密 takeSnapshotLabel 截取快照 startRecordingLabel 开始录制 stopRecordingLabel 停止录制 IncallFullscreenWindow takeSnapshotLabel 截取快照 startRecordingLabel 开始录制 stopRecordingLabel 停止录制 InviteFriends enterEmailLabel 朋友的电子邮箱地址 messageLabel 消息 cancel 取消 confirm 确定 inviteFriendsTitle 邀请朋友 defaultMessage %1 想要邀请你到 %2 ! defaultSubject %1 邀请 forcedMessage 下载该应用程序到您的电脑并开始免费与用户畅聊 点击这里:<a href="%1">%1</a> MainWindow mainSearchBarPlaceholder 搜索联系人,并开始通话或聊天 homeEntry 主页 contactsEntry 联系人 autoAnswerStatus 自动 smartSearchBarTooltip 使用智能搜索栏直接开始语音或视频通话 、发送消息或添加新联系人。只需键入 您朋友的 SIP 地址或用户名即可。 newConferenceButton 开始电话会议 MainWindowMenuBar settings 偏好设置 about 关于 quit 退出 MainWindowTopMenuBar settings 偏好 about 关于 quit 退出 ManageAccounts ok selectPresenceLabel 在线状态 selectAccountLabel 活动账户 Message menuCopy 复制 menuPlayMe 玩玩看! MultimediaParameters ok Notifier newVersionAvailable 新版本( %1 )可用! newFileMessage 收到新附件! OnlineInstallerDialog confirm 确定 onlineInstallerExtractingDescription 正在解压 %1 … onlineInstallerDownloadingDescription 正在下载 %1 … onlineInstallerFinishedDescription %1 已成功安装! onlineInstallerFailedDescription %1 安装失败! OutgoingMessage messageError 错误 messageRead 读取 messageDelivered 已送达 Presence presenceOnline 有空 presenceBusy 忙碌 presenceDoNotDisturb 请勿打扰 presenceOffline 离线 SettingsAdvanced logsTitle 日志 logsFolderLabel 日志文件夹 sendLogs 发送日志 logsUploadUrlLabel 日志上传服务器地址 logsUploadFailed 上传日志失败 logsEnabledLabel 启用日志 cleanLogs 清理日志 cleanLogsDescription 你确定要移除所有日志吗? developerSettingsTitle 开发者设置 developerSettingsEnabledLabel 启用开发者设置 logsMailerFailed Message when Linphone try to open a mailer to send logs, after uploading them to the server (%1 would be the upload url) 找不到邮件程序,但日志已上传到 %1 logsMailerSuccess 日志已上传到 %1 SettingsAudio audioTitle 音频参数 playbackDeviceLabel 播放设备 captureDeviceLabel 捕获设备 ringerDeviceLabel 响铃设备 ringLabel 响铃 echoCancellationLabel 启用回音消除 audioCodecsTitle 音频编解码器 showAudioCodecsLabel 显示音频编解码器 playbackGainLabel 播放增益 captureGainLabel 捕获增益 audioTestLabel 捕获级别 audioSettingsInCallWarning 音频通话正在进行中:某些设置不可用。 SettingsCallsChat fileServerLabel 文件服务器 encryptWithLimeLabel 使用 LIME 加密 limeDisabled 已禁用 limeRequired 必须 limePreferred 偏好 chatTitle 聊天 callsTitle 通话 encryptionLabel 加密 noEncryption autoAnswerLabel 自动接听 autoAnswerDelayLabel 延时(毫秒) autoAnswerWithVideoLabel 自动接听(使用视频) chatEnabledLabel 启用聊天 callRecorderEnabledLabel 启用通话录制器 chatNotificationSoundEnabledLabel 启用通知铃声 chatNotificationSoundLabel 通知铃声 conferenceEnabledLabel 启用会议 contactsTitle 联系人 contactsEnabledLabel 启用联系人 muteMicrophoneEnabledLabel 启用麦克风静音 outgoingCallsEnabledLabel 启用去电 showTelKeypadAutomaticallyLabel 自动显示拨号盘 automaticallyRecordCallsLabel 自动录制通话 keepCallsWindowInBackgroundLabel 在后台保留通话窗口 callPauseEnabledLabel 暂挂通话已启用 encryptionMandatoryLabel 硬化是强制性的 SettingsNetwork sendDtmfsLabel DTMF 发送方式 allowIpV6Label 允许 IPv6 transportTitle 传输 natAndFirewallTitle NAT 和防火墙 enableIceLabel 启用 ICE stunServerLabel STUN/TURN 服务器 enableTurnLabel 启用 TURN turnUserLabel TURN 用户名 turnPasswordLabel TURN 密码 networkProtocolAndPortsTitle 网络协议和端口 sipUdpPortLabel SIP UDP 端口 sipTcpPortLabel SIP TCP 端口 audioRtpUdpPortLabel 音频 RTP UDP 端口 videoRtpUdpPortLabel 视频 RTP UDP 端口 dscpFieldsTitle DSCP 域 sipFieldLabel SIP audioRtpStreamFieldLabel 音频 RTP 串流 videoRtpStreamFieldLabel 视频 RTP 串流 bandwidthControlTitle 带宽控制 downloadSpeedLimitLabel 下载速度限制 Kbit/s uploadSpeedLimitLabel 上传速度限制 Kbit/s enableAdaptiveRateControlLabel 启用自适应控流 presenceTitle 在线状态 rlsUriLabel 使用 RLS URI rlsUriAuto 自动 rlsUriDisabled 永不 showNetworkSettingsLabel 显示网络设置 generalTitle 将军 SettingsSipAccounts defaultIdentityTitle 默认身份 defaultUsernameLabel 用户名 defaultSipAddressLabel SIP 地址 proxyAccountsTitle 代理账户 eraseAllPasswords 删除所有密码 addAccount 添加帐户 editHeader 编辑 deleteHeader 删除 deleteAccountDescription 您确定要删除此帐户吗? eraseAllPasswordsDescription 是否确定要删除所有密码? defaultDisplayNameLabel 显示名称 assistantTitle 助理 createAppSipAccountEnabledLabel 启用账户创建 useAppSipAccountEnabledLabel 启用账户使用情况 useOtherSipAccountEnabledLabel 启用通用账户使用 fetchRemoteConfigurationEnabledLabel 启用配置提取 assistantSupportsPhoneNumbersLabel 支持电话号码 SettingsSipAccountsEdit sipAddressLabel SIP 地址 transportLabel 交通工具 serverAddressLabel SIP 服务器地址 registrationDurationLabel 登记期限 (秒) routeLabel 路线 contactParamsLabel 联系参数 publishPresenceLabel 发布状况信息 avpfIntervalLabel AVPF常规RTCP间隔(秒) registerEnabledLabel 注册 avpfEnabledLabel 启用 AVPF cancel 取消 confirm 确认 invalidSipAddress SIP 地址无效。 invalidServerAddress 无效的服务器地址。 invalidRoute 无效的路线。 enableIceLabel 启用 ICE stunServerLabel STUN/TURN服务器 enableTurnLabel 启用TURN turnUserLabel TURN用户 turnPasswordLabel TURN密码 natAndFirewallTitle NAT 和防火墙 mainSipAccountSettingsTitle 主 SIP 帐户设置 SettingsUi pathsTitle 路径 savedScreenshotsLabel 已保存的截图文件夹 savedCallsLabel 已保存的呼叫文件夹 languagesTitle 语言 languagesLabel 语言 systemLocale 系统区域设置 cleanAvatars 擦除头像 cleanAvatarsDescription 你确定要擦掉所有的化身? downloadLabel 下载文件夹 setLocaleDescription 有必要重新启动应用程序。 你想立即重新启动吗? otherTitle 其他 exitOnCloseLabel 在关闭窗口中退出应用程序 dataTitle 用户界面数据 autoStartLabel 自动启动应用程序 SettingsVideo videoInputDeviceLabel 视频输入设备 videoFramerateLabel 帧率 videoCaptureTitle 视频捕捉参数 videoPresetLabel 视频预设 presetDefault 默认值 presetHighFps 高 FPS presetCustom 定制 videoSizeLabel 视频分辨率 videoCodecsTitle 视频编解码器 showCameraPreview 视频预览 showVideoCodecsLabel 显示视频编解码器 videoSettingsInCallWarning 视频呼叫正在进行中:某些设置不可用。 SettingsVideoPreview confirm SettingsWindow settingsTitle 设置 sipAccountsTab SIP 账户 audioTab 音频 videoTab 视频 callsAndChatTab 通话和聊天 networkTab 网络 uiTab 用户界面 validButton uiAdvanced 先进 SmartSearchBar addContact 添加联系人 Timeline timelineTitle 以前 UseAppSipAccount confirmAction 使用 useAppSipAccountTitle 使用 %1 账户 useUsernameToLogin 使用用户名和密码,而不是您的电话号码。 quitWarning 您的账户已创建,但尚未验证。 是否确定要退出此视图? UseAppSipAccountWithPhoneNumber countryLabel 国家 phoneNumberLabel 电话号码 UseAppSipAccountWithUsername usernameLabel 用户名 passwordLabel 密码 UseOtherSipAccount confirmAction 使用 useOtherSipAccountTitle 使用 SIP 帐户 usernameLabel 用户名 displayNameLabel 显示名称(可选) sipDomainLabel SIP 域 passwordLabel 密码 transportLabel 交通工具 addOtherSipAccountError 无法添加此账户。 ZrtpTokenAuthentication confirmSas 与同行确认以下 SAS。 codeA 说: codeB 您的联系人应该说: deny 否认 accept 确认 country Afghanistan 阿富汗 Albania 阿尔巴尼亚 Algeria 阿尔及利亚 AmericanSamoa 美属萨摩亚 Andorra 安道尔 Angola 安哥拉 Anguilla 安圭拉 AntiguaAndBarbuda 安提瓜和巴布达 Argentina 阿根廷 Armenia 亚美尼亚 Aruba 阿魯巴 Australia 澳大利亚 Austria 奥地利 Azerbaijan 阿塞拜疆 Bahamas 巴哈马 Bahrain 巴林 Bangladesh 孟加拉国 Barbados 巴巴多斯 Belarus 白俄罗斯 Belgium 比利时 Belize 伯利兹 Benin 贝宁 Bermuda 百慕大 Bhutan 不丹 Bolivia 玻利维亚 BosniaAndHerzegowina 波斯尼亚和黑塞哥维那 Botswana 博茨瓦纳 Brazil 巴西 Brunei 文莱 Bulgaria 保加利亚 BurkinaFaso 布基纳法索 Burundi 布隆迪 Cambodia 柬埔寨 Cameroon 喀麦隆 Canada 加拿大 CapeVerde 佛得角 CaymanIslands 开曼群岛 CentralAfricanRepublic 中非共和国 Chad 乍得 Chile 智利 China 中国 Colombia 哥伦比亚 Comoros 科摩罗 PeoplesRepublicOfCongo 刚果共和国 DemocraticRepublicOfCongo 刚果民主共和国 CookIslands 库克群岛 CostaRica 哥斯达黎加 IvoryCoast 象牙海岸 Croatia 克罗地亚 Cuba 古巴 Cyprus 塞浦路斯 CzechRepublic 捷克共和国 Denmark 丹麦 Djibouti 吉布提 Dominica 多米尼克 DominicanRepublic 多米尼加共和国 Ecuador 厄瓜多尔 Egypt 埃及 ElSalvador 萨尔瓦多 EquatorialGuinea 赤道几内亚 Eritrea 厄立特里亚 Estonia 爱沙尼亚 Ethiopia 埃塞俄比亚 FalklandIslands 福克兰群岛 FaroeIslands 法罗群岛 Fiji 斐济 Finland 芬兰 France 法国 FrenchGuiana 法属圭亚那 FrenchPolynesia 法属波利尼西亚 Gabon 加蓬 Gambia 冈比亚 Georgia 格鲁吉亚 Germany 德国 Ghana 加纳 Gibraltar 直布罗陀 Greece 希腊 Greenland 格陵兰 Grenada 格林纳达 Guadeloupe 瓜德罗普岛 Guam 关岛 Guatemala 危地马拉 Guinea 几内亚 GuineaBissau 几内亚比绍 Guyana 圭亚那 Haiti 海地 Honduras 洪都拉斯 HongKong 香港 Hungary 匈牙利 Iceland 冰岛 India 印度 Indonesia 印度尼西亚 Iran 伊朗 Iraq 伊拉克 Ireland 爱尔兰 Israel 以色列 Italy 意大利 Jamaica 牙买加 Japan 日本 Jordan 约旦 Kazakhstan 哈萨克斯坦 Kenya 肯尼亚 Kiribati 基里巴斯 DemocraticRepublicOfKorea 朝鲜民主主义人民共和国 RepublicOfKorea 大韩民国 Kuwait 科威特 Kyrgyzstan 吉尔吉斯斯坦 Laos 老挝 Latvia 拉脱维亚 Lebanon 黎巴嫩 Lesotho 莱索托 Liberia 利比里亚 Libya 利比亚 Liechtenstein 列支敦士登 Lithuania 立陶宛 Luxembourg 卢森堡 Macau 澳门 Macedonia 马其顿 Madagascar 马达加斯加 Malawi 马拉维 Malaysia 马来西亚 Maldives 马尔代夫 Mali 马里 Malta 马耳他 MarshallIslands 马绍尔群岛 Martinique 马提尼克 Mauritania 毛里塔尼亚 Mauritius 毛里求斯 Mayotte 马约特 Mexico 墨西哥 Micronesia 密克罗尼西亚 Moldova 摩尔多瓦 Monaco 摩纳哥 Mongolia 蒙古 Montenegro 黑山 Montserrat 蒙特塞拉特 Morocco 摩洛哥 Mozambique 莫桑比克 Myanmar 缅甸 Namibia 纳米比亚 NauruCountry 瑙鲁 Nepal 尼泊尔 Netherlands 荷兰 NewCaledonia 新喀里多尼亚 NewZealand 新西兰 Nicaragua 尼加拉瓜 Niger 尼日尔 Nigeria 尼日利亚 Niue 纽埃 NorfolkIsland 諾福克島 NorthernMarianaIslands 北马里亚纳群岛 Norway 挪威 Oman 阿曼 Pakistan 巴基斯坦 Palau 帕劳 PalestinianTerritories 巴勒斯坦领土 Panama 巴拿马 PapuaNewGuinea 巴布亚新几内亚 Paraguay 巴拉圭 Peru 秘鲁 Philippines 菲律宾 Poland 波兰 Portugal 葡萄牙 PuertoRico 波多黎各 Qatar 卡塔尔 Reunion 团聚 Romania 罗马尼亚 RussianFederation 俄罗斯联邦 Rwanda 卢旺达 SaintHelena 圣赫勒拿岛 SaintKittsAndNevis 圣基茨和尼维斯 SaintLucia 圣卢西亚 SaintPierreAndMiquelon 圣皮埃尔和密克隆岛 SaintVincentAndTheGrenadines 圣文森特和格林纳丁斯 Samoa 萨摩亚 SanMarino 圣马力诺 SaoTomeAndPrincipe 圣多美和普林西比 SaudiArabia 沙特阿拉伯 Senegal 塞内加尔 Serbia 塞尔维亚 Seychelles 塞舌尔 SierraLeone 塞拉利昂 Singapore 新加坡 Slovakia 斯洛伐克 Slovenia 斯洛文尼亚 SolomonIslands 所罗门群岛 Somalia 索马里 SouthAfrica 南非 Spain 西班牙 SriLanka 斯里兰卡 Sudan 苏丹 Suriname 苏里南 Swaziland 斯威士兰 Sweden 瑞典 Switzerland 瑞士 Syria 叙利亚 Taiwan 台湾 Tajikistan 塔吉克斯坦 Tanzania 坦桑尼亚 Thailand 泰国 Togo 多哥 Tokelau 托克劳 Tonga 汤加 TrinidadAndTobago 特立尼达和多巴哥 Tunisia 突尼斯 Turkey 土耳其 Turkmenistan 土库曼斯坦 TurksAndCaicosIslands 特克斯和凯科斯群岛 Tuvalu 图瓦卢 Uganda 乌干达 Ukraine 乌克兰 UnitedArabEmirates 阿拉伯联合酋长国 UnitedKingdom 大不列颠及北爱尔兰联合王国 UnitedStates 美国 Uruguay 乌拉圭 Uzbekistan 乌兹别克斯坦 Vanuatu 瓦努阿图 Venezuela 委内瑞拉 Vietnam 越南 WallisAndFutunaIslands 瓦利斯和富图纳群岛 Yemen 也门 Zambia 赞比亚 Zimbabwe 津巴布韦 linphone-utils downloadCodecDescription 是否要下载 %1 (%2)? linphone-desktop-4.2.5/linphone-app/assets/linphone.desktop.cmake000066400000000000000000000006271376717241300252070ustar00rootroot00000000000000[Desktop Entry] Name=@APPLICATION_NAME@ GenericName=SIP Phone Comment=@APPLICATION_DESCRIPTION@ Type=Application Exec=@EXECUTABLE_NAME@ %u Icon=@EXECUTABLE_NAME@ Terminal=false Categories=Network;Telephony; MimeType=x-scheme-handler/sip-linphone;x-scheme-handler/sip;x-scheme-handler/sips-linphone;x-scheme-handler/sips;x-scheme-handler/tel;x-scheme-handler/callto; X-PulseAudio-Properties=media.role=phone linphone-desktop-4.2.5/linphone-app/assets/linphonerc-factory000066400000000000000000000002411376717241300244420ustar00rootroot00000000000000[misc] version_check_url_root=https://linphone.org/releases log_collection_upload_server_url=https://www.linphone.org:444/lft.php [sound] ec_filter=MSWebRTCAEC linphone-desktop-4.2.5/linphone-app/assets/qt.conf.in000066400000000000000000000001211376717241300226060ustar00rootroot00000000000000[Platforms] WindowsArguments = dpiawareness=@APP_QT_CONF_DPI@ @APP_QT_CONF_PATH@ linphone-desktop-4.2.5/linphone-app/build/000077500000000000000000000000001376717241300205115ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/build/CMakeLists.txt000066400000000000000000000040141376717241300232500ustar00rootroot00000000000000############################################################################ # CMakeLists.txt # Copyright (C) 2018 Belledonne Communications, Grenoble France # ############################################################################ # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # ############################################################################ if(NOT CPACK_PACKAGE_NAME) set(CPACK_PACKAGE_NAME "linphone") endif () set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/../../LICENSE.txt") set(CPACK_PACKAGE_VERSION_MAJOR ${PROJECT_VERSION_MAJOR}) set(CPACK_PACKAGE_VERSION_MINOR ${PROJECT_VERSION_MINOR}) set(CPACK_PACKAGE_VERSION_PATCH ${PROJECT_VERSION_PATCH}) set(CPACK_PACKAGE_FILE_NAME ${CPACK_PACKAGE_NAME}-${PROJECT_VERSION}) set(CPACK_SOURCE_GENERATOR "TGZ") set(CPACK_SOURCE_IGNORE_FILES "^${PROJECT_SOURCE_DIR}/.git*" "^${CMAKE_BINARY_DIR}" "/\\\\..+" "OUTPUT" "WORK" "linphone-sdk" "cmake_builder" "submodules" "qt5.spec" "libmng.spec" ) bc_compute_full_version(PROJECT_VERSION_BUILD) if(PROJECT_VERSION_BUILD) set(CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}-${PROJECT_VERSION_BUILD}") endif() message("-- Package file name is ${CPACK_PACKAGE_FILE_NAME}") set(CPACK_SOURCE_PACKAGE_FILE_NAME ${CPACK_PACKAGE_FILE_NAME}) bc_generate_rpm_specfile("rpm/linphone.spec.cmake" "${PROJECT_SOURCE_DIR}/linphone.spec") include(CPack) linphone-desktop-4.2.5/linphone-app/build/rpm/000077500000000000000000000000001376717241300213075ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/build/rpm/linphone.spec.cmake000066400000000000000000000046571376717241300250720ustar00rootroot00000000000000# -*- rpm-spec -*- %define _prefix @CMAKE_INSTALL_PREFIX@ %define pkg_prefix @BC_PACKAGE_NAME_PREFIX@ %define _datarootdir %{_prefix}/share %define _datadir %{_datarootdir} %define _docdir %{_datadir}/doc %define build_number @PROJECT_VERSION_BUILD@ %if %{build_number} %define build_number_ext -%{build_number} %endif Name: @CPACK_PACKAGE_NAME@ Version: @PROJECT_VERSION@ Release: %{build_number}%{?dist} Summary: A free (libre) SIP video-phone. Group: Communications/Telephony License: GPL URL: https://www.linphone.org Source0: %{name}-%{version}%{?build_number_ext}.tar.gz BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-buildroot Requires: %{pkg_prefix}bctoolbox Requires: %{pkg_prefix}belcard Requires: %{pkg_prefix}liblinphone Requires: %{pkg_prefix}mediastreamer Requires: %{pkg_prefix}minizip Requires: %{pkg_prefix}qt %description A free (libre) SIP video-phone. %if 0%{?rhel} && 0%{?rhel} <= 7 %global cmake_name cmake3 %define ctest_name ctest3 %else %global cmake_name cmake %define ctest_name ctest %endif %define custom_debug_package %{!?_enable_debug_packages:%debug_package}%{?_enable_debug_package:%{nil}} %custom_debug_package %prep %setup -n %{name}-%{version}%{?build_number_ext} %build %{expand:%%%cmake_name} . -DCMAKE_BUILD_TYPE=@CMAKE_BUILD_TYPE@ -DCMAKE_PREFIX_PATH:PATH=%{_prefix} @RPM_ALL_CMAKE_OPTIONS@ make %{?_smp_mflags} %install make install DESTDIR=%{buildroot} %clean rm -rf $RPM_BUILD_ROOT %post /sbin/ldconfig for i in 16 22 24 32 64 128 do xdg-icon-resource install --novendor --mode system --theme hicolor --context apps --size $i %{_datarootdir}/icons/hicolor/${i}x${i}/apps/linphone.png linphone done xdg-desktop-menu install --novendor --mode system %{_datarootdir}/applications/linphone.desktop %postun xdg-desktop-menu uninstall --mode system linphone.desktop for i in 16 22 24 32 64 128 do xdg-icon-resource uninstall --mode system --theme hicolor --context apps --size $i linphone done /sbin/ldconfig %files %defattr(-,root,root,-) %doc LICENSE.txt CHANGELOG.md README.md %{_bindir}/ %{_datadir}/ %changelog * Tue Nov 27 2018 ronan.abhamon - Do not set CMAKE_INSTALL_LIBDIR and never with _libdir! * Thu Mar 15 2018 ronan.abhamon - Initial RPM release. linphone-desktop-4.2.5/linphone-app/build/rpm/qt5.spec000066400000000000000000000057021376717241300227000ustar00rootroot00000000000000# -*- rpm-spec -*- %define _qt5_version 5.10 %define _qt5_dir /opt/com.belledonne-communications/linphone %define _qt5_archdatadir %{_qt5_dir} %define _qt5_bindir %{_qt5_dir}/bin %define _qt5_docdir %{_qt5_dir}/doc %define _qt5_headerdir %{_qt5_dir}/include %define _qt5_libdir %{_qt5_dir}/lib %define _qt5_plugindir %{_qt5_dir}/plugins %define _qt5_translationdir %{_qt5_dir}/translations Name: linphone-qt Summary: Qt5 Version: %{_qt5_version} Release: 1 License: LGPLv2 with exceptions or GPLv3 with exceptions Url: http://qt-project.org/ Source0: %{name}-%{version}.tar.gz BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-buildroot %description Qt is a software toolkit for developing applications. %package devel Summary: Development libraries for liblinphone Group: Development/Libraries Requires: %{name} = %{version}-%{release} %description devel Qt is a software toolkit for developing applications. %prep %setup -n %{name}-%{version} %build ./configure \ -opensource \ -confirm-license \ -release \ -shared \ -c++std c++11 \ -silent \ -nomake examples \ -nomake tests \ -qt-freetype \ -qt-harfbuzz \ -qt-libjpeg \ -qt-libpng \ -qt-pcre \ -qt-xcb \ -qt-xkbcommon \ -skip wayland \ -system-zlib \ -archdatadir %{_qt5_archdatadir} \ -bindir %{_qt5_bindir} \ -docdir %{_qt5_docdir} \ -headerdir %{_qt5_headerdir} \ -libdir %{_qt5_libdir} \ -plugindir %{_qt5_plugindir} \ -prefix %{_qt5_dir} \ -translationdir %{_qt5_translationdir} make %install make install INSTALL_ROOT=%{buildroot} %files %defattr(-,root,root,-) %license LICENSE.LGPL* LGPL_EXCEPTION.txt LICENSE.FDL %{_qt5_archdatadir}/phrasebooks/*.qph %{_qt5_archdatadir}/qml/ %{_qt5_bindir}/ %{_qt5_docdir}/global/ %{_qt5_libdir}/libQt5*.so.5* %{_qt5_plugindir}/audio/*.so %{_qt5_plugindir}/bearer/*.so %{_qt5_plugindir}/canbus/*.so %{_qt5_plugindir}/designer/libqquickwidget.so %{_qt5_plugindir}/egldeviceintegrations/*.so %{_qt5_plugindir}/gamepads/libevdevgamepad.so %{_qt5_plugindir}/generic/*.so %{_qt5_plugindir}/geometryloaders/*.so %{_qt5_plugindir}/iconengines/libqsvgicon.so %{_qt5_plugindir}/imageformats/*.so %{_qt5_plugindir}/mediaservice/libqtmedia_audioengine.so %{_qt5_plugindir}/platforminputcontexts/*.so %{_qt5_plugindir}/platforms/*.so %{_qt5_plugindir}/playlistformats/libqtmultimedia_m3u.so %{_qt5_plugindir}/qmltooling/*.so %{_qt5_plugindir}/renderplugins/libscene2d.so %{_qt5_plugindir}/sceneparsers/*.so %{_qt5_plugindir}/sqldrivers/*.so %{_qt5_plugindir}/xcbglintegrations/*.so %{_qt5_translationdir}/ %files devel %defattr(-,root,root,-) %{_qt5_archdatadir}/mkspecs/ %{_qt5_headerdir}/Qt*/ %{_qt5_libdir}/*.a %{_qt5_libdir}/*.la %{_qt5_libdir}/*.prl %{_qt5_libdir}/cmake/Qt5*/*.cmake %{_qt5_libdir}/libQt5*.so %{_qt5_libdir}/pkgconfig/Qt5*.pc %changelog * Wed Dec 12 2018 Ghislain Mary - Simplify %files sections * Wed Mar 21 2018 Ronan Abhamon - Initial RPM linphone-desktop-4.2.5/linphone-app/cmake/000077500000000000000000000000001376717241300204725ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/cmake/FindMinizip.cmake000066400000000000000000000031311376717241300237120ustar00rootroot00000000000000############################################################################ # FindMinizip.cmake # Copyright (C) 2018 Belledonne Communications, Grenoble France # ############################################################################ # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # ############################################################################ # # - Find the minizip include file and library # # MINIZIP_FOUND - system has minizip # MINIZIP_INCLUDE_DIRS - the minizip include directory # MINIZIP_LIBRARIES - The libraries needed to use minizip find_path(MINIZIP_INCLUDE_DIRS NAMES mz.h PATH_SUFFIXES include ) if(MINIZIP_INCLUDE_DIRS) set(HAVE_MZ_H 1) endif() find_library(MINIZIP_LIBRARIES NAMES minizip minizipd ) include(FindPackageHandleStandardArgs) find_package_handle_standard_args(Minizip DEFAULT_MSG MINIZIP_INCLUDE_DIRS MINIZIP_LIBRARIES HAVE_MZ_H ) mark_as_advanced(MINIZIP_INCLUDE_DIRS MINIZIP_LIBRARIES HAVE_MZ_H) linphone-desktop-4.2.5/linphone-app/cmake_builder/000077500000000000000000000000001376717241300222005ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/cmake_builder/additional_steps.cmake000066400000000000000000000066351376717241300265420ustar00rootroot00000000000000############################################################################ # additional_steps.cmake # Copyright (C) 2017-2018 Belledonne Communications, Grenoble France # ############################################################################ # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # ############################################################################ include("${CMAKE_CURRENT_LIST_DIR}/../application_info.cmake") if (LINPHONE_BUILDER_TARGET STREQUAL linphoneqt AND WIN32) # Create a shortcut to linphone.exe in install prefix. set(SHORTCUT_PATH "${CMAKE_INSTALL_PREFIX}/${EXECUTABLE_NAME}.lnk") set(SHORTCUT_TARGET_PATH "${CMAKE_INSTALL_PREFIX}/bin/${EXECUTABLE_NAME}.exe") set(SHORTCUT_WORKING_DIRECTORY "${CMAKE_INSTALL_PREFIX}") configure_file("${CMAKE_CURRENT_LIST_DIR}/linphone_package/windows/winshortcut.vbs.in" "${CMAKE_CURRENT_BINARY_DIR}/winshortcut.vbs" @ONLY) add_custom_command(OUTPUT "${SHORTCUT_PATH}" COMMAND "cscript" "${CMAKE_CURRENT_BINARY_DIR}/winshortcut.vbs") add_custom_target(linphoneqt_winshortcut ALL DEPENDS "${SHORTCUT_PATH}" TARGET_linphone_builder) # Create a shortcut to the solution file in the top directory. set(SHORTCUT_PATH "${CMAKE_SOURCE_DIR}/../../Project.sln.lnk") set(SHORTCUT_TARGET_PATH "${LINPHONE_BUILDER_WORK_DIR}/cmake/Project.sln") set(SHORTCUT_WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/../..") configure_file("${CMAKE_CURRENT_LIST_DIR}/linphone_package/windows/winshortcut.vbs.in" "${CMAKE_CURRENT_BINARY_DIR}/solutionshortcut.vbs" @ONLY) execute_process(COMMAND "cscript" "${CMAKE_CURRENT_BINARY_DIR}/solutionshortcut.vbs") endif () # Packaging. if (ENABLE_PACKAGING) get_cmake_property(_varnames VARIABLES) set(ENABLE_VARIABLES ) foreach (_varname ${_varnames}) if (_varname MATCHES "^ENABLE_.*") list(APPEND ENABLE_VARIABLES -D${_varname}=${${_varname}}) endif () endforeach () if (LINPHONE_BUILDER_TARGET STREQUAL linphoneqt) # Linphone and linphone SDK packages. linphone_builder_apply_flags() linphone_builder_set_ep_directories(linphone_package) linphone_builder_expand_external_project_vars() ExternalProject_Add(TARGET_linphone_package DEPENDS TARGET_linphone_builder TMP_DIR ${ep_tmp} BINARY_DIR ${ep_build} SOURCE_DIR "${CMAKE_CURRENT_LIST_DIR}/linphone_package" DOWNLOAD_COMMAND "" CMAKE_GENERATOR ${CMAKE_GENERATOR} CMAKE_ARGS ${LINPHONE_BUILDER_EP_ARGS} -DCMAKE_INSTALL_PREFIX=${LINPHONE_BUILDER_WORK_DIR}/PACKAGE -DTOOLS_DIR=${CMAKE_BINARY_DIR}/programs -DLINPHONE_OUTPUT_DIR=${CMAKE_INSTALL_PREFIX} -DLINPHONE_DESKTOP_DIR=${CMAKE_CURRENT_LIST_DIR}/.. -DLINPHONE_SOURCE_DIR=${EP_linphone_SOURCE_DIR} ${ENABLE_VARIABLES} -DLINPHONE_BUILDER_SIGNING_IDENTITY=${LINPHONE_BUILDER_SIGNING_IDENTITY} ) endif () endif () linphone-desktop-4.2.5/linphone-app/cmake_builder/install.cmake000066400000000000000000000027111376717241300246510ustar00rootroot00000000000000############################################################################ # packaging.cmake # Copyright (C) 2020 Belledonne Communications, Grenoble France # ############################################################################ # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # ############################################################################ include(../application_info.cmake) if (APPLE) #execute_process(COMMAND install_name_tool -id "@executable_path/../lib/libminizip.dylib" "${CMAKE_INSTALL_PREFIX}/lib/libminizip.dylib") execute_process(COMMAND install_name_tool -add_rpath "@executable_path/../Frameworks/" "${CMAKE_BINARY_DIR}/${EXECUTABLE_NAME}") execute_process(COMMAND install_name_tool -add_rpath "@executable_path/../lib/" "${CMAKE_BINARY_DIR}/${EXECUTABLE_NAME}") else () endif () linphone-desktop-4.2.5/linphone-app/cmake_builder/linphone_package/000077500000000000000000000000001376717241300254675ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/cmake_builder/linphone_package/CMakeLists.txt000066400000000000000000000555741376717241300302470ustar00rootroot00000000000000################################################################################ # # Copyright (c) 2017-2020 Belledonne Communications SARL. # # This file is part of linphone-desktop # (see https://www.linphone.org). # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # ################################################################################ cmake_minimum_required(VERSION 3.1) project(LINPHONE_PACKAGE) # Dummy project. if(ENABLE_BUILD_VERBOSE) message("Linphone-packages paths : ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}") endif() include("${CMAKE_CURRENT_SOURCE_DIR}/../../application_info.cmake") find_package(Git) #Policy set to allow link from other directory (cmake 3.13) if (POLICY CMP0079) cmake_policy(SET CMP0079 NEW) endif () set(LINPHONE_QML_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../ui") # ============================================================================== # Build package version. # ============================================================================== bc_compute_full_version(APP_PROJECT_VERSION) if (GIT_EXECUTABLE AND NOT(APP_PROJECT_VERSION)) execute_process( COMMAND ${GIT_EXECUTABLE} describe --always OUTPUT_VARIABLE APP_PROJECT_VERSION OUTPUT_STRIP_TRAILING_WHITESPACE WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/../.." ) elseif (NOT(APP_PROJECT_VERSION)) set(APP_PROJECT_VERSION "0.0.0") endif () string(REGEX REPLACE "([0-9.]+)-?.*" "\\1" LINPHONE_VERSION "${APP_PROJECT_VERSION}") string(REPLACE "." ";" SPLITTED_LINPHONE_VERSION "${LINPHONE_VERSION}") list(LENGTH SPLITTED_LINPHONE_VERSION SPLITTED_LINPHONE_VERSION_LENGTH) list(GET SPLITTED_LINPHONE_VERSION 0 LINPHONE_MAJOR_VERSION) list(GET SPLITTED_LINPHONE_VERSION 1 LINPHONE_MINOR_VERSION) if (SPLITTED_LINPHONE_VERSION_LENGTH GREATER 2) list(GET SPLITTED_LINPHONE_VERSION 2 LINPHONE_MICRO_VERSION) endif () set(PACKAGE_VERSION "${APP_PROJECT_VERSION}") message(STATUS "Versions : ${APP_PROJECT_VERSION}, ${LINPHONE_VERSION}") # ============================================================================== # Preparing the Linphone SDK bundle. # ============================================================================== if (WIN32) set(LIBDIR ${CMAKE_INSTALL_BINDIR}) set(LIBPREFIX "") set(LIBEXT "dll") set(PLUGINEXT "dll") elseif (APPLE) set(LIBDIR ${CMAKE_INSTALL_LIBDIR}) set(LIBPREFIX "lib") set(LIBEXT "dylib") set(PLUGINEXT "so") endif () # Removed unless it is useful to get a zip from SDK : The SDK is packaged with binaries. #if (WIN32) # find_program(7Z_PROGRAM 7z PATHS "$ENV{ProgramFiles}/7-Zip") # if (7Z_PROGRAM) # execute_process( # COMMAND ${7Z_PROGRAM} a -tzip ${CMAKE_BINARY_DIR}/${EXECUTABLE_NAME}-sdk-${APP_PROJECT_VERSION}-win32.zip "@${EXECUTABLE_NAME}-sdk.list" # WORKING_DIRECTORY ${LINPHONE_OUTPUT_DIR} # ) # else () # message(WARNING "7z has not been found, cannot generate the SDK!") # endif () #elseif (APPLE) # execute_process( # COMMAND rm -rf "${CMAKE_BINARY_DIR}/${EXECUTABLE_NAME}-sdk-${APP_PROJECT_VERSION}-mac.zip" # COMMAND zip -ry "${CMAKE_BINARY_DIR}/${EXECUTABLE_NAME}-sdk-${APP_PROJECT_VERSION}-mac.zip" . -i "@${EXECUTABLE_NAME}-sdk.list" # WORKING_DIRECTORY ${LINPHONE_OUTPUT_DIR} # ) #endif () # ============================================================================== # Specific deployment. # ============================================================================== set(APP_QT_CONF_DPI "1") if (WIN32) find_program(DEPLOYQT_PROGRAM windeployqt) if (NOT DEPLOYQT_PROGRAM) message(FATAL_ERROR "Could not find the windeployqt program. Make sure it is in the PATH.") endif () file(GLOB LIB_FILES "${LINPHONE_OUTPUT_DIR}/${CMAKE_INSTALL_LIBDIR}/*.dll") install(FILES ${LIB_FILES} DESTINATION "${CMAKE_INSTALL_BINDIR}/") file(GLOB LIB_FILES "${LINPHONE_OUTPUT_DIR}/${CMAKE_INSTALL_BINDIR}/*.dll") if( ENABLE_OPENH264)# Remove openH264 lib from the installation. this codec will be download by user foreach(item ${LIB_FILES}) get_filename_component(LIBRARY_FILENAME ${item} NAME) if("${LIBRARY_FILENAME}" MATCHES "^openh264.*.dll$") list(REMOVE_ITEM LIB_FILES ${item}) endif() endforeach(item) endif() install(FILES ${LIB_FILES} DESTINATION "${CMAKE_INSTALL_BINDIR}/") file(GLOB EXE_FILES "${LINPHONE_OUTPUT_DIR}/${CMAKE_INSTALL_BINDIR}/*.exe") if(MSVC AND (CMAKE_BUILD_TYPE STREQUAL "Debug" OR CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo")) file(GLOB PDB_FILES "${LINPHONE_OUTPUT_DIR}/${CMAKE_INSTALL_BINDIR}/*.pdb") install(FILES ${PDB_FILES} DESTINATION "${CMAKE_INSTALL_BINDIR}/" PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE) file(GLOB PDB_FILES "${LINPHONE_OUTPUT_DIR}/${CMAKE_INSTALL_LIBDIR}/*.pdb") install(FILES ${PDB_FILES} DESTINATION "${CMAKE_INSTALL_BINDIR}/" PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE) endif() install(FILES ${EXE_FILES} DESTINATION "${CMAKE_INSTALL_BINDIR}/") file(GLOB PLUGINS_FILES "${LINPHONE_OUTPUT_DIR}/${CMAKE_INSTALL_LIBDIR}/mediastreamer/plugins/*") install(FILES ${PLUGINS_FILES} DESTINATION "plugins/mediastreamer/" ) file(GLOB GRAMMAR_FILES "${LINPHONE_OUTPUT_DIR}/${CMAKE_INSTALL_DATAROOTDIR}/Belr/grammars/*") install(FILES ${GRAMMAR_FILES} DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/belr/grammars/" ) install(DIRECTORY "${LINPHONE_OUTPUT_DIR}/${CMAKE_INSTALL_DATAROOTDIR}/images" DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}" USE_SOURCE_PERMISSIONS OPTIONAL) install(DIRECTORY "${LINPHONE_OUTPUT_DIR}/${CMAKE_INSTALL_DATAROOTDIR}/sounds" DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}" USE_SOURCE_PERMISSIONS) install(FILES "${LINPHONE_OUTPUT_DIR}/${CMAKE_INSTALL_DATAROOTDIR}/Linphone/rootca.pem" DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/${EXECUTABLE_NAME}/") install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/../../assets/linphonerc-factory" DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/${EXECUTABLE_NAME}") set(APP_QT_CONF_DPI "0") set(APP_QT_CONF_PATH "") configure_file("${CMAKE_CURRENT_SOURCE_DIR}/../../assets/qt.conf.in" "${CMAKE_CURRENT_BINARY_DIR}/../../qt.conf" @ONLY) install(FILES "${CMAKE_CURRENT_BINARY_DIR}/../../qt.conf" DESTINATION "${CMAKE_INSTALL_BINDIR}") install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/../../assets/assistant" DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/${EXECUTABLE_NAME}" USE_SOURCE_PERMISSIONS) install( CODE "execute_process(COMMAND ${DEPLOYQT_PROGRAM} \"\${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_BINDIR}/${EXECUTABLE_NAME}.exe\" -qmldir=${LINPHONE_QML_DIR} --compiler-runtime)")# -verbose=2)" COMPONENT binary_application) # list(REMOVE_ITEM SHARE_CONTENT "${CMAKE_INSTALL_DATAROOTDIR}/belr" "${CMAKE_INSTALL_DATAROOTDIR}/Belr" "${CMAKE_INSTALL_DATAROOTDIR}/images" "${CMAKE_INSTALL_DATAROOTDIR}/${APPLICATION_NAME}" "${CMAKE_INSTALL_DATAROOTDIR}/${APPLICATION_NAME}" "${CMAKE_INSTALL_DATAROOTDIR}/sounds") # foreach (ITEM IN LISTS SHARE_CONTENT) # list(APPEND SHARE_CONTENT_EXCLUDE PATTERN "${ITEM}" EXCLUDE) # endforeach () elseif (APPLE) configure_file("${CMAKE_CURRENT_SOURCE_DIR}/macos/Info.plist.in" "${CMAKE_CURRENT_BINARY_DIR}/../../Info.plist" @ONLY) configure_file("${CMAKE_CURRENT_SOURCE_DIR}/macos/entitlements.xml.in" "${CMAKE_CURRENT_BINARY_DIR}/../../entitlements.xml" @ONLY) configure_file("${CMAKE_CURRENT_SOURCE_DIR}/macos/linphone.icns" "${CMAKE_CURRENT_BINARY_DIR}/../../${EXECUTABLE_NAME}.icns" COPYONLY) if(ENABLE_APP_PACKAGING) set(APP_QT_CONF_PATH "[Paths]\nPlugins = PlugIns\nImports = Resources/qml\nQml2Imports = Resources/qml") else() set(APP_QT_CONF_PATH "") endif() configure_file("${CMAKE_CURRENT_SOURCE_DIR}/../../assets/qt.conf.in" "${CMAKE_CURRENT_BINARY_DIR}/../../qt.conf" @ONLY) install(FILES "${CMAKE_CURRENT_BINARY_DIR}/../../qt.conf" DESTINATION "${APPLICATION_NAME}.app/Contents/Resources/") install(FILES "${CMAKE_CURRENT_BINARY_DIR}/../../Info.plist" DESTINATION "${APPLICATION_NAME}.app/Contents") install(FILES "${CMAKE_CURRENT_BINARY_DIR}/../../${EXECUTABLE_NAME}.icns" DESTINATION "${APPLICATION_NAME}.app/Contents/Resources") install( CODE "execute_process(COMMAND rsync -a \"${LINPHONE_OUTPUT_DIR}/Frameworks\" \"\${CMAKE_INSTALL_PREFIX}/${APPLICATION_NAME}.app/Contents/\" )") #Use rsync to bypass symlinks override issues of frameworks file(GLOB SHARED_LIBRARIES "${LINPHONE_OUTPUT_DIR}/${CMAKE_INSTALL_LIBDIR}/lib*.dylib") if( ENABLE_OPENH264 )# Remove openH264 lib from the installation. this codec will be download by user foreach(item ${SHARED_LIBRARIES}) get_filename_component(LIBRARY_FILENAME ${item} NAME) if("${LIBRARY_FILENAME}" MATCHES "^libopenh264.*.dylib$") list(REMOVE_ITEM SHARED_LIBRARIES ${item}) endif() endforeach(item) endif() install(FILES ${SHARED_LIBRARIES} DESTINATION "${APPLICATION_NAME}.app/Contents/Frameworks") file(GLOB GRAMMAR_FILES "${LINPHONE_OUTPUT_DIR}/${CMAKE_INSTALL_DATAROOTDIR}/Belr/grammars/*") install(FILES ${GRAMMAR_FILES} DESTINATION "${APPLICATION_NAME}.app/Contents/Resources/${CMAKE_INSTALL_DATAROOTDIR}/belr/grammars/") install(DIRECTORY "${LINPHONE_OUTPUT_DIR}/${CMAKE_INSTALL_DATAROOTDIR}/images" DESTINATION "${APPLICATION_NAME}.app/Contents/Resources/${CMAKE_INSTALL_DATAROOTDIR}" USE_SOURCE_PERMISSIONS OPTIONAL) install(DIRECTORY "${LINPHONE_OUTPUT_DIR}/${CMAKE_INSTALL_DATAROOTDIR}/sounds" DESTINATION "${APPLICATION_NAME}.app/Contents/Resources/${CMAKE_INSTALL_DATAROOTDIR}" USE_SOURCE_PERMISSIONS) install(FILES "${LINPHONE_OUTPUT_DIR}/${CMAKE_INSTALL_DATAROOTDIR}/Linphone/rootca.pem" DESTINATION "${APPLICATION_NAME}.app/Contents/Resources/${CMAKE_INSTALL_DATAROOTDIR}/${EXECUTABLE_NAME}") install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/../../assets/linphonerc-factory" DESTINATION "${APPLICATION_NAME}.app/Contents/Resources/${CMAKE_INSTALL_DATAROOTDIR}/${EXECUTABLE_NAME}") install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/../../assets/assistant" DESTINATION "${APPLICATION_NAME}.app/Contents/Resources/${CMAKE_INSTALL_DATAROOTDIR}/${EXECUTABLE_NAME}" USE_SOURCE_PERMISSIONS) file(GLOB SHARED_LIBRARIES "${CMAKE_CURRENT_BINARY_DIR}/../../${APPLICATION_NAME}.app/Contents/Frameworks/lib*.dylib") foreach (LIBRARY ${SHARED_LIBRARIES}) get_filename_component(LIBRARY_FILENAME ${LIBRARY} NAME) message("Changing RPATH of ${LIBRARY_FILENAME} from '${LINPHONE_OUTPUT_DIR}/${CMAKE_INSTALL_LIBDIR}' to '@executable_path/../Frameworks'") execute_process(COMMAND install_name_tool -rpath "${LINPHONE_OUTPUT_DIR}/${CMAKE_INSTALL_LIBDIR}" "@executable_path/../Frameworks" "${LIBRARY}") endforeach () install( CODE "execute_process(COMMAND install_name_tool -add_rpath \"@executable_path/../Frameworks/\" \"\${CMAKE_INSTALL_PREFIX}/${APPLICATION_NAME}.app/Contents/MacOS/${EXECUTABLE_NAME}\")") install( CODE "execute_process(COMMAND install_name_tool -add_rpath \"@executable_path/../lib/\" \"\${CMAKE_INSTALL_PREFIX}/${APPLICATION_NAME}.app/Contents/MacOS/${EXECUTABLE_NAME}\")") if(ENABLE_APP_PACKAGING) find_program(DEPLOYQT_PROGRAM macdeployqt) if (NOT DEPLOYQT_PROGRAM) message(FATAL_ERROR "Could not find the macdeployqt program. Make sure it is in the PATH.") endif() install( CODE "execute_process(COMMAND ${DEPLOYQT_PROGRAM} \${CMAKE_INSTALL_PREFIX}/${APPLICATION_NAME}.app -qmldir=${LINPHONE_QML_DIR})") endif() if (LINPHONE_BUILDER_SIGNING_IDENTITY) install(CODE "file(GLOB FRAMEWORKS_NAMES \"\${CMAKE_INSTALL_PREFIX}/${APPLICATION_NAME}.app/Contents/Frameworks/*\") foreach (FRAMEWORK \${FRAMEWORKS_NAMES}) execute_process(COMMAND \"codesign\" \"--options\" \"runtime,library\" \"--force\" \"--deep\" \"--verbose\" \"-s\" \"${LINPHONE_BUILDER_SIGNING_IDENTITY}\" \"\${FRAMEWORK}\") endforeach ()") install( CODE "execute_process(COMMAND \"codesign\" \"--force\" \"--deep\" \"--options\" \"runtime,library\" \"--verbose\" \"-s\" \"${LINPHONE_BUILDER_SIGNING_IDENTITY}\" \"\${CMAKE_INSTALL_PREFIX}/${APPLICATION_NAME}.app/Contents/Frameworks/mediastreamer2.framework/Versions/A/Libraries/libmswebrtc.so\")") install( CODE "execute_process(COMMAND \"codesign\" \"--entitlements\" \"${CMAKE_CURRENT_BINARY_DIR}/../../entitlements.xml\" \"--force\" \"--deep\" \"--options\" \"runtime,library\" \"--verbose\" \"-s\" \"${LINPHONE_BUILDER_SIGNING_IDENTITY}\" \"\${CMAKE_INSTALL_PREFIX}/${APPLICATION_NAME}.app\")") endif () # install(DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${APPLICATION_NAME}.app" DESTINATION "." USE_SOURCE_PERMISSIONS) else()# Not Windows and Apple foreach (LIBRARY ${SHARED_LIBRARIES}) get_filename_component(LIBRARY_FILENAME ${LIBRARY} NAME) message("Changing RPATH of ${LIBRARY_FILENAME} from '${LINPHONE_OUTPUT_DIR}/${CMAKE_INSTALL_LIBDIR}' to '$ORIGIN/../${CMAKE_INSTALL_LIBDIR}'") execute_process(COMMAND install_name_tool -rpath "${LINPHONE_OUTPUT_DIR}/${CMAKE_INSTALL_LIBDIR}" "$ORIGIN/../lib" "${LIBRARY}") execute_process(COMMAND install_name_tool -addrpath "$ORIGIN/../lib64" "${LIBRARY}") endforeach () install(DIRECTORY "${LINPHONE_OUTPUT_DIR}/${CMAKE_INSTALL_BINDIR}/" DESTINATION "${CMAKE_INSTALL_BINDIR}" USE_SOURCE_PERMISSIONS) #Just in case. This is useless because we have to use CMAKE_INSTALL_LIBDIR if( EXISTS "${LINPHONE_OUTPUT_DIR}/lib/") file(GLOB SHARED_LIBRARIES "${LINPHONE_OUTPUT_DIR}/lib/*.so*") if( ENABLE_OPENH264 )# Remove openH264 lib from the installation. this codec will be download by user foreach(item ${SHARED_LIBRARIES}) get_filename_component(LIBRARY_FILENAME ${item} NAME) if("${LIBRARY_FILENAME}" MATCHES "^libopenh264.*$") list(REMOVE_ITEM SHARED_LIBRARIES ${item}) endif() endforeach(item) endif() install(FILES ${SHARED_LIBRARIES} DESTINATION "lib") endif() if( EXISTS "${LINPHONE_OUTPUT_DIR}/lib64/") file(GLOB SHARED_LIBRARIES "${LINPHONE_OUTPUT_DIR}/lib64/*.so*") if( ENABLE_OPENH264 )# Remove openH264 lib from the installation. this codec will be download by user foreach(item ${SHARED_LIBRARIES}) get_filename_component(LIBRARY_FILENAME ${item} NAME) if("${LIBRARY_FILENAME}" MATCHES "^libopenh264.*$") list(REMOVE_ITEM SHARED_LIBRARIES ${item}) endif() endforeach(item) endif() install(FILES ${SHARED_LIBRARIES} DESTINATION "lib64") endif() install(DIRECTORY "${LINPHONE_OUTPUT_DIR}/${CMAKE_INSTALL_DATAROOTDIR}/" DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}" USE_SOURCE_PERMISSIONS) if(ENABLE_BUILD_VERBOSE) message("INSTALLATION : ${LINPHONE_OUTPUT_DIR}/${CMAKE_INSTALL_DATAROOTDIR}/" ) endif() file(GLOB PLUGINS_FILES "${LINPHONE_OUTPUT_DIR}/${CMAKE_INSTALL_LIBDIR}/mediastreamer/plugins/*") install(FILES ${PLUGINS_FILES} DESTINATION "plugins/mediastreamer/" ) # Install desktop/icon files. configure_file("${CMAKE_CURRENT_SOURCE_DIR}/../../assets/linphone.desktop.cmake" "${CMAKE_CURRENT_BINARY_DIR}/../../${EXECUTABLE_NAME}.desktop" @ONLY) install(FILES "${CMAKE_CURRENT_BINARY_DIR}/../../${EXECUTABLE_NAME}.desktop" DESTINATION "${CMAKE_INSTALL_DATADIR}/applications") set(APP_QT_CONF_PATH "") configure_file("${CMAKE_CURRENT_SOURCE_DIR}/../../assets/qt.conf.in" "${CMAKE_CURRENT_BINARY_DIR}/../../qt.conf" @ONLY) install(FILES "${CMAKE_CURRENT_BINARY_DIR}/../../qt.conf" DESTINATION "${CMAKE_INSTALL_BINDIR}") install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/../../assets/images/linphone_logo.svg" DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/scalable/apps/" RENAME "${EXECUTABLE_NAME}.svg") install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/../../assets/linphonerc-factory" DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/${EXECUTABLE_NAME}") install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/../../assets/assistant" DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/${EXECUTABLE_NAME}" USE_SOURCE_PERMISSIONS) set(ICON_DIRS 16x16 22x22 24x24 32x32 64x64 128x128 256x256) foreach (DIR ${ICON_DIRS}) install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/../../assets/icons/hicolor/${DIR}/apps/icon.png" DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/${DIR}/apps/" RENAME "${EXECUTABLE_NAME}.png") endforeach () endif () if (MSVC) # string(REGEX REPLACE "Visual Studio ([0-9]+).*" "\\1" MSVC_VERSION "${CMAKE_GENERATOR}") include(InstallRequiredSystemLibraries) set(MSVC_VERSION ${MSVC_TOOLSET_VERSION}) set(CMAKE_INSTALL_UCRT_LIBRARIES TRUE) if (CMAKE_BUILD_TYPE STREQUAL "Debug") set(CMAKE_INSTALL_DEBUG_LIBRARIES TRUE) endif() find_file(UCRTBASE_LIB "ucrtbase.dll" PATHS "C:/Windows/System32") install(FILES ${UCRTBASE_LIB} DESTINATION "${CMAKE_INSTALL_BINDIR}") # find_file(MSVCP_LIB "msvcp${MSVC_VERSION}0.dll" PATHS "C:/Windows/System32") # # Starting with Visual Studio 2015 (MSVC_VERSION==14) the msvcr dll has been renamed to vcruntime. # find_file(VCRUNTIME_LIB "vcruntime${MSVC_VERSION}0.dll" PATHS "C:/Windows/System32") # if (NOT VCRUNTIME_LIB) # find_file(VCRUNTIME_LIB "msvcr${MSVC_VERSION}0.dll" PATHS "C:/Windows/System32") # endif () # message("MSDIRS : ${MSVCP_LIB} ${UCRTBASE_LIB} ${VCRUNTIME_LIB} => ${MSVC_VERSION}, ${CMAKE_GENERATOR}") # install(FILES ${MSVCP_LIB} ${UCRTBASE_LIB} ${VCRUNTIME_LIB} DESTINATION "${CMAKE_INSTALL_BINDIR}") # if (CMAKE_BUILD_TYPE STREQUAL "Debug") # find_file(MSVCPD_LIB "msvcp${MSVC_VERSION}0d.dll" PATHS "C:/Windows/System32") # find_file(UCRTBASED_LIB "ucrtbased.dll" PATHS "C:/Windows/System32") # find_file(VCRUNTIMED_LIB "vcruntime${MSVC_VERSION}0d.dll" PATHS "C:/Windows/System32") # if (NOT VCRUNTIMED_LIB) # find_file(VCRUNTIMED_LIB "msvcr${MSVC_VERSION}0d.dll" PATHS "C:/Windows/System32") # endif () # install(FILES ${MSVCPD_LIB} ${UCRTBASED_LIB} ${VCRUNTIMED_LIB} DESTINATION "${CMAKE_INSTALL_BINDIR}") # endif () endif () # ============================================================================== # CPack. # ============================================================================== if(${ENABLE_APP_PACKAGING}) set(CPACK_BINARY_STGZ OFF) set(CPACK_BINARY_TGZ OFF) set(CPACK_BINARY_TZ OFF) set(CPACK_PACKAGE_NAME "${APPLICATION_NAME}") set(CPACK_PACKAGE_VENDOR "${APPLICATION_VENDOR}") set(CPACK_PACKAGE_VERSION_MAJOR ${LINPHONE_MAJOR_VERSION}) set(CPACK_PACKAGE_VERSION_MINOR ${LINPHONE_MINOR_VERSION}) if (LINPHONE_MICRO_VERSION) set(CPACK_PACKAGE_VERSION_PATCH ${LINPHONE_MICRO_VERSION}) endif () set(CPACK_PACKAGE_EXECUTABLES "${EXECUTABLE_NAME};${APPLICATION_NAME}") set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/../../../LICENSE.txt") set(CPACK_PACKAGE_INSTALL_DIRECTORY "${APPLICATION_NAME}") set(CPACK_PACKAGE_DIRECTORY "${CMAKE_INSTALL_PREFIX}/Packages") set(CPACK_PACKAGE_ICON "${CMAKE_CURRENT_SOURCE_DIR}/../../assets/icon.ico") set(PERFORM_SIGNING 0) if (APPLE) set(CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}-${PACKAGE_VERSION}-mac") set(CPACK_DMG_BACKGROUND_IMAGE "${CMAKE_CURRENT_SOURCE_DIR}/macos/background_dmg.jpg") configure_file("${CMAKE_CURRENT_SOURCE_DIR}/macos/linphone_dmg.scpt.in" "${CMAKE_CURRENT_BINARY_DIR}/linphone_dmg.scpt" @ONLY) set(CPACK_DMG_DS_STORE_SETUP_SCRIPT "${CMAKE_CURRENT_BINARY_DIR}/linphone_dmg.scpt") set(CPACK_BINARY_DRAGNDROP ON) message(STATUS "Set DragNDrop CPack generator in OUTPUT/Packages") elseif(NOT(WIN32)) set(DO_APPIMAGE YES) set(CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}-${PACKAGE_VERSION}") message(STATUS "Set AppImage CPack generator in OUTPUT/Packages") else() set(CPACK_GENERATOR "NSIS") set(DO_GENERATOR YES) set(CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}-${PACKAGE_VERSION}-win32") string(COMPARE EQUAL ${CPACK_GENERATOR} "NSIS" IS_NSIS) if (${IS_NSIS}) set(PACKAGE_EXT "exe") # Use magic `NSIS.template.in` template from the current source directory to force uninstallation # and ensure that linphone is not running before installation. set(CPACK_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/windows") set(CPACK_PACKAGE_ICON "${CMAKE_CURRENT_SOURCE_DIR}\\\\windows\\\\nsis_banner.bmp") set(CPACK_NSIS_MUI_ICON "${CMAKE_CURRENT_SOURCE_DIR}/../../assets/icon.ico") set(CPACK_NSIS_MUI_UNIICON "${CMAKE_CURRENT_SOURCE_DIR}/../../assets/icon.ico") set(CPACK_NSIS_DISPLAY_NAME "${APPLICATION_NAME}") if (LINPHONE_MICRO_VERSION) set(CPACK_NSIS_PACKAGE_NAME "${APPLICATION_NAME} ${LINPHONE_MAJOR_VERSION}.${LINPHONE_MINOR_VERSION}.${LINPHONE_MICRO_VERSION}") else () set(CPACK_NSIS_PACKAGE_NAME "${APPLICATION_NAME} ${LINPHONE_MAJOR_VERSION}.${LINPHONE_MINOR_VERSION}") endif () set(CPACK_NSIS_URL_INFO_ABOUT ${APPLICATION_URL}) file(TO_NATIVE_PATH "${CMAKE_CURRENT_BINARY_DIR}" DOS_STYLE_BINARY_DIR) string(REPLACE "\\" "\\\\" ESCAPED_DOS_STYLE_BINARY_DIR "${DOS_STYLE_BINARY_DIR}") configure_file("${CMAKE_CURRENT_SOURCE_DIR}/windows/install.nsi.in" "${CMAKE_CURRENT_BINARY_DIR}/install.nsi" @ONLY) set(CPACK_NSIS_EXTRA_INSTALL_COMMANDS "!include \\\"${ESCAPED_DOS_STYLE_BINARY_DIR}\\\\install.nsi\\\"") configure_file("${CMAKE_CURRENT_SOURCE_DIR}/windows/uninstall.nsi.in" "${CMAKE_CURRENT_BINARY_DIR}/uninstall.nsi" @ONLY) set(CPACK_NSIS_EXTRA_UNINSTALL_COMMANDS "!include \\\"${ESCAPED_DOS_STYLE_BINARY_DIR}\\\\uninstall.nsi\\\"") set(CPACK_NSIS_EXECUTABLES_DIRECTORY "bin") set(CPACK_NSIS_MUI_FINISHPAGE_RUN "${EXECUTABLE_NAME}.exe") message(STATUS "Set NSIS CPack generator in OUTPUT/Packages") else () set(PACKAGE_EXT "msi") set(CPACK_WIX_UPGRADE_GUID "C748668E-53D0-4088-A548-E33A76615A3B") set(CPACK_WIX_PRODUCT_ICON "${CMAKE_CURRENT_SOURCE_DIR}/../../assets/icon.ico") set(CPACK_WIX_PROPERTY_ARPURLINFOABOUT "${APPLICATION_URL}") message(STATUS "Set MSI CPack generator in OUTPUT/Packages") # TODO: Deal with install/uninstall.nsi endif () if(LINPHONE_WINDOWS_SIGNING_DIR) # Sign the installer. set(TIMESTAMP_URL "http://timestamp.verisign.com/scripts/timestamp.dll") set(PFX_FILE "${LINPHONE_WINDOWS_SIGNING_DIR}/linphone.pfx") set(PASSPHRASE_FILE "${LINPHONE_WINDOWS_SIGNING_DIR}/passphrase.txt") get_filename_component(WINSDK_DIR "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Microsoft SDKs\\Windows;CurrentInstallFolder]" REALPATH CACHE) find_program(SIGNTOOL signtool PATHS ${WINSDK_DIR}/${CMAKE_INSTALL_BINDIR}) if (EXISTS ${PFX_FILE}) if (SIGNTOOL) set(SIGNTOOL_COMMAND ${SIGNTOOL}) message("Found signtool and certificate ${PFX_FILE}") set(PERFORM_SIGNING 1) else () message(STATUS "Could not find signtool! Code signing disabled (${SIGNTOOL})") endif () else () message(STATUS "No signtool certificate found; assuming development machine (${PFX_FILE})") endif () endif () endif() configure_file("${CMAKE_CURRENT_SOURCE_DIR}/packaging.cmake.in" "${CMAKE_CURRENT_BINARY_DIR}/packaging.cmake" @ONLY) install(SCRIPT "${CMAKE_CURRENT_BINARY_DIR}/packaging.cmake") include(CPack) endif() linphone-desktop-4.2.5/linphone-app/cmake_builder/linphone_package/macos/000077500000000000000000000000001376717241300265715ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/cmake_builder/linphone_package/macos/Info.plist.in000066400000000000000000000057161376717241300311570ustar00rootroot00000000000000 CFBundleDevelopmentRegion English CFBundleName @APPLICATION_NAME@ CFBundleDisplayName @APPLICATION_NAME@ CFBundleExecutable @EXECUTABLE_NAME@ CFBundleGetInfoString @PACKAGE_VERSION@, (C) 2011-2020 @APPLICATION_NAME@ @APPLICATION_URL@ CFBundleIconFile @EXECUTABLE_NAME@.icns CFBundleIdentifier @APPLICATION_ID@ CFBundleInfoDictionaryVersion 6.0 CFBundlePackageType APPL CFBundleShortVersionString @PACKAGE_VERSION@ CFBundleSignature ???? CFBundleVersion @PACKAGE_VERSION@ NSHumanReadableCopyright Copyright 2011-2020 @APPLICATION_VENDOR@ LSMinimumSystemVersion @CMAKE_OSX_DEPLOYMENT_TARGET@ NSAppSleepDisabled YES CFBundleURLTypes CFBundleURLName @APPLICATION_ID@ CFBundleURLSchemes sip sip-linphone sips sips-linphone tel callto NSPrincipalClass NSApplication NSHighResolutionCapable True NSCameraUsageDescription Streaming Video between devices NSMicrophoneUsageDescription Streaming Audio between devices NSPhotoLibraryUsageDescription Store attachment and allow camera record when selected NSPhotoLibraryAddUsageDescription Store attachment and allow camera record when selected NSDesktopFolderUsageDescription Storing configuration files NSDocumentsFolderUsageDescription Can use Documents folder to put logs NSDownloadsFolderUsageDescription Getting files from Download folder for sending attachment NSAppleEventsUsageDescription Used for sending notifications and working with Appnap NSBluetoothPeripheralUsageDescription Use for wireless headsets kTCCServiceMediaLibrary Used media library as attachement or for the ringer com.apple.security.device.camera com.apple.security.device.microphone com.apple.security.device.audio-input com.apple.security.personal-information.photos-library linphone-desktop-4.2.5/linphone-app/cmake_builder/linphone_package/macos/background_dmg.jpg000066400000000000000000000463061376717241300322520ustar00rootroot00000000000000JFIFHHExifMM*>F(iNHH02100100http://ns.adobe.com/xap/1.0/ 72 72 Inch Exif Version 2.1 FlashPix Version 1.0 Uncalibrated 700 450 CC   1Q1sh;[Ff[$ s,e?lKX-%8ud }>~=غDe#r*`깠6FW%<2XU4\?he^⹸]~u^Pr Cm,uYeF^YWV~'hLem"un9b'l+-*K9ٔUYxzhUĸG[Ut"+Jd-#+Y@|?!;Xygp ,!JPR[#'LY==S1ЫKaMcwKcR#>GEPxG~ܕ{DuN:hy1~`͹ tpbr@)]2,2h9SEhRE#8H͌dm#;(d=u#S(yd=uH {B/7`56P 04@7!Lu?aESGpe[iiM(v^eDkyqm'Fn.c06}-@8%͉ xH(t-/KY7N.ΩV !PR#pp(=R6R+`QSZ2 ӕW[n:owLh+ CpqH)1ZgT,SdU-ȴNE[nDfpWwS+pUcq/.%ũ4~suw=' RZ0u,(yj:Ou^h<-Չ.$0, `hxjO^$,[ɉiծ_#-MBur`MF2ãs#0X7-t] ҕU_/ Oa`'k? SLT5tYس ]AF$6hIKxA5P@%bX0Np ؜)`<;a=vsF"z|z _[o'$( %~??3 !"$12`a#3AQSTbqs?iy]L81v!ln|0"6~wqu ;d;WUǶNj_n#F6q۫Ub?(9Ϸ"T2ޗ3!Ĕ2cvmBl!MMh3٪mvYahڦMl 0(!( iO/P%+Z+'YUq$ H̺*\4lX,t޸xlχN=5,=/Wn^ח*?3n-`bl}n\!Y͛IB>[0$P {wz 98P2Ƀko?W::~eKKcë# ?4~PB2DбYX2a R@FHJ"FU;[r??wrk,q(5VfՇ1 @9~c8?: 1!`A0P"#$2QSTabrs?>W҆䡯g]_m] 2눧pa 'zI]$Gej=b(x431,nk7{Z99 ݙ_ef Q@"NCEnT6 tKP8hs\2vypqKj(_jaMQ%,=ǫ c^GTMwD5EP;z!#Z,uAG![J`v w\hUʹW*\`JM;X>Q  !"1A#2BQ`tu$346PRabvSdqs 05@CTc?6k_x})VvܺsH@#YgDwuqT<oVS7VǛ&n60#)3< Q柼RWc Hv2Jt>?m-C.)S6#ܫVyWX!Y1N-182Zƒ]"OHc"3dsЖ?xq:FCd|.z)Ȳ#½[2`&^X=b6Okj*J@AǬ?Z u'q˥?k|O|Aslخ3r- u ^>kkrv WPh޵tޜmyK%oϞ&8nZdQ v +XH# mvgTګټByL|SGN{ /:,&gF(&;j\QfZa^VN(蓍s&\%r}ds[kJ0==%O%6䬻U׫tkXA{}&L='>^@j1Zy$~"@i>[!BX#]UCvQ{uY<^$\p1)&'oGzl[qžRMS l[dMf3"C11:O͸ɯ ~6ӽhm)R HT!IR~ap51.^[ jPs%z@_5aq$C Ql=*ژ⟸Oix+fW>Nӈb^‹F"§'ޘYeY_n9{n>R~SJo]%Cc5ic;wYkZg圅Thc)G&U&Æ[bjԭp,r0u,"gʼ6.΃%I6ݱ}|@4/ū {GZ y䢵H :n>$ȀȔ*/EC GԈX׻%1S拘,*L$[D-,U85R)`׺ `FOo_!ʯ<}V; 3[a-/3Y>RCsY1[#s=/ۦ K]oR[53\,W.fa%<8׌Ze|vM~:5;FCsϫ}[KNTS-X-QY|VOYHڵY"1ߋxЫ 2Kee^R% kf gth#_2zV& WZzWPI#,iOs>XĪ[]VYomTk&ӔdMĀ chr?O!_SR~~_/ڶer6elRMnx89y_z YfAʟ4@Az*8 vkO9sj㳹iN 8edLS^fNE:Zמ?˱ 8r}gfG'L9Kܷ9N9K謇j[ z;!TQjm140u,v,SBd31Pz@ }jf4-,χ9RW`xV3zܶTĎ:Oc{"WղѴ!_11Rrǁ\+Du3s%=Q2c}[\r",+!wMYLNƯXbhq _)QvOC#Zո'vYܭcyK<27;Jp.mm^Sœz}s6{2ylvlۭ?qXDFjO]6L>gG3MF8AsM%u $q{޳zM^*/7ClX9dD"=k[.y{_ίڕ^=}n#;H2(Hj}v) N=+cW+}vޠmml5c]L"rWk,]LCoN" QZwr[du`iIu9Б o4fuڬD/t4ao_s8n\G'J[5 R䲻4jr\{cIx/ūbd2IN2K+7NZ[4N:ݸk1*4;p~OI~$.O=̦xWx*0/|J5u3xzY*DgV[0LQL0{c-e^F-Z;y%LV Mժ4Z|1+\jckԬ$}A4͓fSxf?/BJVuIO} cD u0t0Q=F }gt_& UDz";p^\UJ-I> "իf̈́O-i+8ɟ.RZ`򴠂Ҳ C<[dbvm+0'=EWAc%>8KV*h"ժEuA02"5"jɋ^QO:aM0GU);hS18|V(+}uS?n{tٷ]m{i11LOx\L|\\^Lb,Hu"^S={mj`vXIۑu֫џ~B*Q^ǏsӅ~3̏~2Q+r9>_GG(=.Om'_g[uІ`=i?wQ#ݴmf7,Xƣ3Ƕ8! "bdfcX;ƾ6az[@A)GqvJb#Rg`c㙈_ζ7nAua1=*OdMORO iTyRq&KYpx_JM[f‹W i6ys4LY K$9 L˸Tlj)/0$F.bm_ji# &%5CkŢ]0~=E4 As'z qz5ߍ[vԛ[D.Y[C`ڔ`}d4՝WAJ>մNRmr]q8~"ckӮ5tWY-,LDZ>bh=/~nMePE@SY jBj0dfu9 OԵxƣT S4B"Z : 7SH㿯^+xGC~S EQ_О^1 z= mڙ&X=iN'\Zm18qβݳ=\:uL 3\{xǧqcb_xug5vԹuJl!N2Q64Pƪ;nljKݴ ' g2*Y)) '[e &BC0BBQv>K[**:6+;zcB[VQ K"ԴE!1xuorb>er~Cl@'ah*&[8 S: k%=3:_?!!!!(J;LLw$0_cRKW,d+9NE!"LV 6 gUG???qSR}n,k!,U^ȉpA"Ŝ O@slԎM8dSL )~G<+'*&-H3lƺLLuoN?s8M;ɵ~T|K9nC `B&-CPALgVDD&~{6*c2ݶDNƬs$R6 bW,"Ni5 f"M7䥎U[b`9`㺕=IJbyq+'ڰRן'(?wyi_ !ZqN%{{[0b-.tƻ֬3+79%|dr284 U,PaiA ^'}/yrh{東%ΰM+Wǵ,"NLkA j2뙈sVŪjڼ 4^BfP(-H+y1N%{{Y4"-dDi.tƻ֬%+6\+!1AQ`a Pq0@?!<ޱ=ku/]TV(q''6/x#?AJ:vSJ_FNE$U}T= Ga.3^e@^{͑vL|v: 5g !^3KݎLlHeT$J@ ?yV z3 }d8cD`R?v-snuCQ2T `yt8Q? Lj'NT)9)gt0sIωY4hMs+l;_=M9aͺXl !8"tvȏ??SpePruv>VŻ,,H[zH2^wl!@OѶ!h:xUrQp'v;حEiRs泝_&h$E',sd9 HAq~/7jOIHbh`@WS )+7 _ dcRK|C3d@9TB ]B k4#ɋt6 E@zEo:#̒:rty eQ(d h0JQS?ALŘuHp8{h%eRF`tZǦ08X29~Jvܗ~fQoz;ptDCS";8‹,E+NK 8Q8< Q@#j D} qw?K)K}~:R\zRQ@FB?) O2⡈TFmz5ncR̺ߧ 3=g;SJ4w2X,Z9CL G{7/%b-b)\5cۻtw3k7}bfV0.b ,A) aJ1jZP0ᛗ8+Z|Ӗo{jROd[M%$qHCܼ6MieN͏:5XkG?\*0NOI4p|V.~n^ Kt1YoM8X90C7/`pE/nc>sú]hADCUݲl ^fQ%EN[=Mg~1Ǯ)C2V-s"R xxKV OiL'1,{Kk|Sj&|tIX[,F^_W&[PRqeB=ar@Uq",0'S&k/cP  s?1@wLz!ݧ^q;_y m5lp-I B Ȉ\4A%H 5 ΰtiT$cUu5ndW61 aLe"6ޏ=\@YVzЄIKsAD!0qLZAzxWq=]#g~!9߆ǰUHʘ*P ^E ɞ6P3ldUi g1.*Q]n&JvHI_.m=ʊ 3w eAitt&_l6&!mwg8`Px}׵+=s_'Cׯ7kͿ~khkzbLhyxK\g0 m*jN|dtw80<IƠHՆF/y]a]=4ya V W1۸!Tő8}Z8U Y0 !iD_Ng' *5Z W[2~;U(JgJ5,ugQϮcLxD0uIyMNfEhRka0/%mV N|c~ׯӘD!s&4a/FPJ~dږ'`<c q <`K6sutnRUn} /.yAh8$blρkç iD%Ub$ˢwd(~ Bw|0Edƥbj-=5P 3GR5bj Ŷؕ6l̂@0C(H-PV_mNcm~fIq'-ķ0} -wc6UZ}?Xj@ ].0;x_}O!R RGR1Is{ QXW2I,1@ AD-40&bVU?1.M/=ӅH2Ew$Uff&K5>Tnެp.Ah*5/79(7ظNL uH4( `qb8^*#+>T,$5 V*2,s\.4 'uPMT [YԃgD #7׮ "[C÷nRs1%S L x' ddȿb>s /w8M] 䡙i ʭ\fW.hx źi% KBĕ28I~jV0oSZ'΀Y7;Uk1j9TU2~&?O,kل}zwMi{ T˫&ZM/H k*iW_d8t< uQyNzM8:JGh YPu\!(G:noXZN]sWU!49v+EX0{+uc`3`n 2rIحc췟:-Ӊk.linphone-desktop-4.2.5/linphone-app/cmake_builder/linphone_package/macos/entitlements.xml.in000066400000000000000000000011741376717241300324360ustar00rootroot00000000000000 com.apple.security.assets.music.read-write com.apple.security.microphone com.apple.security.device.camera com.apple.security.device.audio-input com.apple.security.network.client com.apple.security.personal-information.photos-library com.apple.security.files.user-selected.read-write linphone-desktop-4.2.5/linphone-app/cmake_builder/linphone_package/macos/linphone.icns000066400000000000000000001121001376717241300312560ustar00rootroot00000000000000icns@ic098 jP ftypjp2 jp2 Ojp2hihdrcolr"cdefjp2cOQ2d#Creator: JasPer Version 1.900.1R \@@HHPHHPHHPHHPHHP]@@HHPHHPHHPHHPHHP]@@HHPHHPHHPHHPHHP]@@HHPHHPHHPHHPHHP ߅8r=^$2{B~nmHyao B_ᵧ('uZ/N|;"w 9FT4x+I )r!T5rfYR'U.Os}UkˋIs\ս.&KVگbz,`߅|,v qJqﲍt:q 89_PeZ2 #h1Jyk68H-nӄm S UC~}7ur%?%b1Ӝp4e{ii.RzM?06ea2Ϥ "hQ pٝ!SVr4P.Ԛs߅ /c.۽ T,z3g3Cu^CWjr(TDڄ0l$Z ¯Yȫs A)SBX^k6=7dI/*:e/:*$Rt3hg VvvYoNqZ=n331źj_*[S,)|Wk`Z]ak7Cc߁yJhmR+M'TWPB} 01` %G) zm:)dRA$끿2~ ,_Q_c=wy:yes1I.?~.b$`AѰ=F:UGcaMJ@ ( ݰW]!7>S_7aiG6G-=`Aq?=PZF_3ɺ=Y]I5hGIIdN$X a`*.7DU-{)7g0%#[vq.)>|DY ѯH$nV{.˰+yN`($wr'`% U'?Ov{+{ JЗ w;@JxW/zB,%ԈA/_3:t3+rw"Q7?HK 2N葬PburILqh?u|t)^LW^#ʚAW +hЦ?xUL5 +&:[|@,72TP %PV(בnl3?uf_M'/^cim*Ş€#?: rSTRQ3.ãY-mEѪ GLIUя'.FnaMLha .ypFCb[W欢Lx Ll}\e1 evX5+T޿OgPC br ?: K' li]^Գf96:|@j5Mn]O>ZLT\|i}ó Wv馏`ږsZ^ g lpqe}؜af<(@jtmRXY\n3& dnk; V"P5l]un[#l49n Ig5Hp(z)K]-&Gm{Dp 2cԆňHA>Xَ:I 1"/`Zc ^Pq.G5b_ڠkKJJ 8g;`2Ń5;Ϛ彃3[Γ F<`]vKqj̯;@ mAHaƗ_BF!i^n$@%==Q$5@:ɪR®UO&ݑzc^K6h=sK"G4@@xMb;5gWl~ 6d}-R&yG,$`|1톭;(}dշY[< DG;Y}8Q58*}Gj%=)&I(1o]NIxU(UntXȞ ܻ`j=5CxX`&~+ t'luqZ@a ;/OawF#9 Dg 8ڇC3%ׯIbb<CrW\P>E4ذfiT,L,<Ëc7F؇$/Vm[ "(˘n<8?!{]Ϫ;Ke7h&LN Yvփ]! 4y==vy(ܐT*giLV4q~b"_,-aFbA[ϘT8j讈=r܌)^R:whű:΀ߚI+.j?|d $QD0U~~қPS= !ꛍ:v{nos}ZT9S`TNun<'\KZ$KW%. ȵpo SRe}@cϛJ|moL)em"MUY̱,|d\zR}5~_m1exnGވg\sE`#YԃȯPh0µ{yQm<# {Bp(8VΥ:TwP4ja|B5NrCPقDjwPb^:bif UZ}Yư@&p\saueWѧnVޙnt}~:`L#WK|wZR C{Pct Vܣ簚Gz%z(h#[D&#hüLz[sK$Kee3E~Dvp'OF J UD{H$ >r@}PY:+\2)V 'FʹkD `܇T PgVKl)Y2[g̼'4bdOqڇ)W?$p9<ãzeä0޴_OHBtM1!PCt㧗V@`'0.߽#0 8J7kj_6:6aĸfmNll9朔>^X9^{k oti)~8k\_[kmIEtA=bR 9YzR*d(#:Yφ=ՠ8q{ExϪ(<,,kGpS3r8& (xP3FЉ'뎡=,Gw͛HkaA^NRkl>aUj R!qO/4>Aذdc9Gxnev{t?մ G%sXz i A੄#r\繍ю")x{Pw/d~S}#DDzSuQ9 N= r :;f*fs1bwF-6(T-w|(ԍOBJE= 7W9U{ !%KPc0|+\yuӺnޢ!UyvՂ0^鰭ȇ9Rh!'R`[$S)2{7_B>;QˏOͬu%YP1"Π>WN ]r\ [,`N %}dX:ToCV+UB;6;:G7gmgP19E(ءhj]%!leǚ30Rv7ŭCъhc$(02N*Zug[l>p5GT@RW%w?N9}6]/,/bHx@xZj00+򁾻˾w0i6t:c1' {w10ĆQ; Η3: ,4;9< { )ݏpF=$[JiJ)_6Fk3VV'pPE^:|$wҡ|d1qi/xV&mW0Knsƍ :|*zڑu946i2oHKL@߻0P 2}FVQ]hبa3rܡ^|6F9@ѿt#%h&Иǫ 4\3n^];8ץW ׵JAQj]?9z M^ Š6}dA 3-9F۠t}x෺;hy@(GIih~eq8)fYYX7ٮ8Gb(EŴL2$,yMI9r-nbԻ34a3o\@<c=QgE`}d26muW0=uƉBRE"1)AWp6A(e->yUf`BPNZ|^*Wh =R{|.sfs R!rM}XI;VD502+Iw)dQ&2P8 ue|ϥB]5Vu}VS A `!T* 0s. ^دLUf3pA+[&VuUsѧ#r e"t8KF@XfTاetw^PRK~ޕ䵲[E 4*CqUNei _0c봹7\lFRMqa;Jx!zBJa~3_ߟJ?@0帳J.<$FĜ+2O}Ae:qW<Mg! oU6u1.l,x,'x Uh͝1S3fz+0ư0|ni"~ۚ{,lO*/ EaxfR㷰E/_T.?[ n]˭[29 xdy,lt,^9O"A*vqFXkD/mlRXfAPXu:рC"*S_}C5k%,zksr[b?\2L!/han չhj-Y rAc>ON`Z =qKv+9i02l;X׹.z8>QEx@;iGr}F)|SM]5O/+X:-#p<.]zAx-AQBu9mǐwF%~o[TBܗ.=y]G*j|_->bP<|cl",.)!:Wͼ{Yꅣ^ck qSU'Sg9 Rbia}vJUсr;{d*$K̚BJecN1cD-ܱ1BHi.j$?\DNދu?Xmѯ( w/^{CHz3^akBjF֧n/lfȍv,*rRr /YR IP4^kqS6*cF'劫hʥZ6BCjImrw~C |)nCoj ˒CAnhE)s7x뼪i":L3UWlȝ;Rdt^yc=/zٍeۚᳲ UrY)g+^ɪ콬ub`Q%hnhr& -hҊ2N]JN6'qU`ӹ `")Tf_B@p~}_*r3qnUnn`W,/.eL!^"4dd}h Қ^ Jd7d pm'QQ\V!2I fPm(/0:3Zi< GVT;]hibtF%FVS O.p&/wɿEީ*XYiYƖ\XLZ.Qy$qޔm)k D Cm _)Ehu@ J_. ` T+?6D7Uq䨹br:lksp|3JM#-ivubhʨ;KGrf)-'->v!fe#4:!r[OT Ӻ 1KxyvzZOlMI l.]4>id>YW8{Чz|K%2f+nA [ۂP ;^2 q.I4H poכo>oXFy0vw.0U(Q+?gT -7 6/VM_5]9O-׊a$- Ǜ:T=cڳ@4[۰^ ;U&ǏEP&7zYa@BqF^ 8@)& in;_z97a B}5i1Pٳf|efw֏?sO̞Aj=05V˪Q ueŨ:Rɯ@Mۤ%C=Af$lP Յfr\aew]*,xMO xF5:;=r8.4!7 KdUt!jNn]9gT hd6գ8>P?~KD{De29aovO>n:n;`H@D\~apLlLs(zA*]2+m\Z*㐋>(aWPW/IR6XF5'Y CB3kė-mWk~Ofy!=AAhJE%R&("0 n)%{@? 'BnuCEHmRp]ܱضOf6MmtMҜJ6J/f:{}PzӤ&#q;4 md+:*ϜH!.-9tK7#!I@oB>p ^Ly]v9AgV) k 0bL!6(k/ TXjܠ`d.cYT h?dCm. &'0Sy\ݔl4-ךnsV#YC5VZ E`-8Ka0S=҈+K*̚_Isex&_FC$S}g|㱢*w" IiMǰ|rrKؑJUւ%{5/E[Fr5~^~Z'NHK>h<cy0E4I.lWH[4#~^cEYth[d k.b`ڻAxCе7dO~w[?'<ش e2LK8ت{7 _K(SV(*[ JC WbfR`"<DTd@B\s/_ Upgһd {xgmJlUђwdD[A1-VX'BI{Ky=)]Ty*Eidյ;bFcrLo&]m\1\\./4ŏohEK`!=y<U Bڦ<&*KMwJs&𾯷FoS1t[]14^7ۥ۫ Aݓ|~`N k)ݔX/J/>ےSv' 8vAkT:pڤ+ohu> wz)r#t:!pMgբ1&!Xi$lխiSe}aa3b5d:Eږc2?E=gLX9L좃ut~~3ލI?X%lHqSM[qץU5~f9؁h x}~(zI pQ>A4jY/6bJXl|?;nXHN"5u%K~ 8@}()?JQ̞z6vʷe PM4:b3"3K*BCgr0$5ImfChly¶-A-.b>ZIsl L$e''a';ä_=>E+аr ]gKn,FQ?۷n%{\ ń>Wd_<uq /m{Qmar >HoQB`Z.7<ɶĝkmeb5u5CySyX"Ng+&s7oo4 Fk Փ71iWw3}/E ss#ҸK>DCmIҽyD%]̼n;zg|nsp*eBL eM!'UwT]Z/sTᣛ*z,V2,--Wi! njo|0a `n慲EV]qLdN!} ZrjAxN_C~Y=INz\:mW%8.ܢHFYjk2.(:Z EYWFR`?-z9(N;BnfªhYƫl:@soQbsjWK;\C%g}Tx5ov!1;b ]%t:@/<>t)\+T^m"4ޏvhqMRb_*[]|\ell!7H[+;AZ&n?Nb%G"N5!Vyf^vA/RS[Mfg,KK+]Hzy.? ,)y * (lk1'tysems /_LLɶ38?+\^0-'!|wEq~fTp_*NQ!(GA\SsrO3nդEE X :;ajT3^&"MNy}VP!ؚJ '4}ߞ)3p~_jt7( yPՋ5ّ T\s?GX_oIV-&+Wp&]SYn#Th SB^Ff_v 8aoăQ%p ]rtѸJLusV~rЪ'Nr3jه7UPj[-6=M8 u##m/`_7&EUlF\5vuغB@1{2KJBckrQ`Rƥ݂xݤ{Bl ;wbjUȧ^h?Ё@/1"3ա^)AsvؓŸ@%7oY2Lǩq0Dd8abo"^\ 4C8R޶uy\ˆV1|vƒχU)| CөSp\C=$,N7v Cbޯj{'̤n{eFFVo1DgVa)Lmu{ty vË9/030 ܲh ¦ލ2q܄H@*eMxrJ=LXUp\/Afĭ{R9sYxzQDqNh?$NW,Sm \v&%mklͷ#x;{x}wf'/fcmq xU678W,Vmiaz\(Wj_,9&cXw#X[ס)xBQp=}yNyGJdZ 1euR»R0lt+b8}4z=>z gG!jZݡlpdy`&(8NT$ í"<0[qhQ+3M'd-wUh~KwP .ҵ(6~+V: 5sr)2+zRGB&qP#MK A\I;8 v O p;RZdr Ë'VX9'@ڐ8bf,E_w dNr?eX{1O$bCg@´z#ؤHC H*RJ"j/3Zyqe38Fە~d/}{)U.ũTplɰneIz*Ű0 [b'2dkX/xg'ZG9}uu|K.ѥyRm.Bs9zAŽ9JwA CTxv'Y#u"M$ 5SZqzJvBj"aCv~aTXc>RQ?B5vL2>\]wλ!n?gӿ᠟Yci i9jxktsޕ-(9Sf6ylvNqj*~[8q[ɽ0:v4c^xUyxWH;U\(QWqDhL6v<8CB#aUKۀ/MI {sR 3Y Un?pll?/g8 D~ h@_hM^t.+a_e!jzA\EU/NX呪xi.N@aM+S ]XnTVbo)a }Ijjk]gj@2yq0ޑxJߚe1f;vg>AI9TL&r&qץYxO<)]gӊƴ)7O%P\1j>G]nl®{1p)7߂K] UKM׍*ߞ%sCw6ϛɰeC@U4ϖ 7xό^Rk@ܑn/ Cr6ln_?#>vޏtHMS|K6sk=SxlU+&Sc^^77]oshT5a2HgiEZ;/tl- ZMߋ6?b+ޥӳ,qOtMvk 0PTɋII!U݅d!9ȲQ"Jtt?դ)3#ڱ~9njp{kuh4~h.23z:%e ă:YEWp~ORSyX**ZNr׮ƽLd)5w>zumM=..J` gpQ>iΤF)D2vU Wt$r?A0;TN4O c3_L_T⟸7TsWrMRV63k:#4l65_][-6au*;$}Uvo_t IѬslbũM?VUؽ0ah'm 'xu6ɪ2/Z?(T3kB8E  S.6cA^m4foΫ{$V ۓ7G+|&>PLP VȀ@%?ouc=+9P5ẗCџݳy[Uwr;v;tJg)rngپu%S,3\p)o!kpls=([38̞##9ӾVh`F?dW6Wچyd_˗C͟ 'î-j: p}PA@ R"IMNJ_$uOYsmU)A1{3n`Hr"**wµp>=nޗ>j\9(D"}Ok o\0LdMxa~[!2Ί?ٗcHFԣI㧬̅1irɨKx;E̋ G;x1OAʣYe)kpH>B~Ljq99NHY hlT?7AZ#\הoBͅ }teJF6&FqL8>e-Jn][ca Tm)C}(N'FeIsl=ѹܗ_z8ҹy",^u? a@rHP8z>:5]]R`%7QaKDnEznq&x31O?9@hkeAfŤ* B.@9 mg1wFAVu$c)1`Su _Q95xHP'<#UʽiVXd8 -Ok):GF66k`7`ۗizWp $^6f}[t,G:l ROeIP`PڏAr!D3iZ#\lyv"Aq}ȕ^RB{8),{\nA ­ 9B0a^`_g1Y}@1lGK*j|8]\.bZ5V~UWo6*k/긚r'YW펳HisF%SMkBJw'kSbw;-c I BCU}׈O̜hLo9(V1ZSkL p3V ,@K']dW!,8@ 3P N$D HikXTQBtzk3}@P J-LUASաvhb:5gÎE4RyסzL6aֽ>$4F.ӧL9G8&OA/-1dnU} :5H S!i9YQ:d8 gٟ /4̵tfu\PK b _ :+D8ЛEXŒT5Z_=w/2K{#+xizpTz^g|$e8ۜQU$BcEMraOl\Ӹ$l SJFxm]n w &x!ޓ>UUĝq݄,G45'{'" 춲!;IwBn/ˍUrU@+#>SLɤ_3߂~ r9dBgqZ@f?'`Zm±vt_^qØ!ɂC.Nfrמ1srVƁPI%Dh'$)yċ)E{;Cȅ1qҕpIkJQL˜;7.J2Nqͥʉlz%=/CmБ "I8,ŅV&Lreǭ82ݝ ;U_Irbp>f. In<|94!^lJj ^}G2M e5 `}Pc2sHA6gku_:f_p%_(hn|A-6^"FUek˿-d>b~t5Hxk^uicLңJ?Y+JeBVw!t[.;]h6tv" aeRכ tYNbPԷ5v "*W%<+]K/m<Ĉ3/ƴ}N \c4;MDb3Y% :5k|j7 ,N' Z8L`G^a ?N~Qk7<4UVZR3w=T\D7>U'-Ѹ._%pp @&bʛdM)} K@z.<6"Iw\%,$Ӊ4=l~aV u4ԟ(V4Kep L /gȨ:!ejY0$U0N"諔Z">z8=28IIJQݓRj#,}.rnL̻< r%kKItL؂,E)w.bw[s2~ȳ̶ ϛUzR%aW`m85||`*p|M>Kk@o_%kC|6RȿAjK@n% 8$D>JT>F0*\>K>J/IᭃA܅k($`FlO{ @/.O;Htih޸j Q>N~먐l'<0xMfórF`UX\(kN07c,!gL/\RJ:-#I%jʂCvll&+cN>;?$%h.}FvF[e)'-tjmS\Nd&b,@R >ډ%ul6%laJ=.v;O fZfLLkZOj KW) <@|[g.;^g7R9T귒wwp&y_B,fʼn8I4TC؆/0v2) r;ɇ?N#GuǀwM b^bUUHce]ۏ, OWjXV؃ȃXf5v]Rh; pdb =VP]i7 kGrK4`[{˛| fy6qEy+漺 0$}!7B ,$ea/Cj8ysze}? `NIVrSDll;eF""?8q%QVo)[P5pS.={~oeLrԿ_*/RfB8u0F!\mrxidS;)[ce]T[tE5mQҦ]ԅWI9:buM;\06pQI>B.3tb8/eE ~^Ϟ /WƯp1 gQW'6)_\IXD*p |iÎf-ֶD=.eOO!z[֧ VX=IKtwR6Z2΂=1怩9pj:SW2]pkHnb 9](b/o]Qqe6{rhM@ qx?V멆{s3 uZgQel  7_hE07/`ⷮq]qJMɄ`(S;~BN;G`@@FPs]J"RVZՒr|S J3y;ZF_QR/?-äJ=>6,g-> Wst3̀H3%3JCdAM R.e16R"e=ZsW^䇵-(~ rs)ELVf]H!C$K e"V̦Ђ  qSgNTz2>m >%~1W(&Xz%3xB'J)ıST>ґ7'Pcj+XyQ s$l{PyH2=QD1, =D4D:5p؟7L QHpV|2J}AfW\)J?0jFJz*(t!Dq-NQ+};Vӳx,XgߔMrOJnl\H$PdrIkIx>@6@Q1W 7dU.c-MP)Ii#dnsbVĽ8;E&.tnA{GQv2M^`De3x-!<$ǪjsFO,C<Fց'dr6];Ɇ 3#x yhUi8[p8ij<>s (:` "N`^r{Qӛ=.D--Dˮ@l*W]=Ah9o>uq ~D&f~d(mIw 94&D> $^Mء_tpN3WFn5b%t<9H[ݬ`( 6>~gGndHb]?'V+iltGiMz(= (0Udi0c<ߨq,ˌ V{6jO%'vN8gGZn 2z$AZhhJ)R/_!$=<~5Ȯ9En4iz2^GigQHݎ柊P$圮=Vڐ::X7>?ɊbTѥNcօ-nLHtI!jZ2<gѪv˯b7WWuf&ROG—B=\6D/-&'4OrùZ O5 U1ltFL2ys,e{7h5pLc2e$<_\NP_G&Fʑ5pWv3( wą?J)0 S36 ;}iz/'QS@M;\]:aMGEާS3/r%(r/ Դ{:c*U-ՂMD3 QP?3A{4"Ab §]rcM5uW/QnآRR DM1tD}?oԥ å,oeAŽTe~tIFyE92YFm.p%lClI>}]{ D@ن^3٢$q\7(dB$=}[z(EՃ۪1<wI§Vf!^Zrَ۲a}ԕMxƁB8OVM%~T+HHd% _}Wy} GưAC ~UƀSMkF|l9-o\iz zc=)O{o0WjWsX4̖,hW]'w ޽>8FS71\˭F}5дlqhȌAO%+Pbt' eu4N<,k1=e?{PTO %/QbT:=qnݛ\U9j٧` /7A(w3ߧ3UH|#ucm%G'&.iD_:IO&J5 啱qq.y<\Y-#\$-kS}_r&#W nn*tbwܞ=e$ \Y0U.S$/*tu/UzE%sNzK~:6z?tMIҌījJXeR~$\WK!UMruQ GV&5z/NTibb!q8X\?ґ(4UZh`N' zjzz51#s lDP-+XI !@ Ρm ,fI$֐3("@V9q4Dyn~g_@YEM(Ո^ (GҫhL}2`J/S"F|wơ*QHZPBH$}]7t^ر0d@sU4%Jm,ęj.ECU$}[û1H!hu)Kwǎj,I2SXl LGaE ;1b9 ot^6b%I?wA{8#9Xz?%:ӿ5j;lߵܻO}Oߗ6ߵb._n}_SQֿN~^/}OjG?ҟw~OssoRPY $9\|;Zi~:ٰ,WI+ ƴCPI3hGBH&7Ⱦ ƈyg \CzdۯXrX.fY^ogM=18fX{ sΤRl,eZi!yCD5WQZ;% OIvx@ㆮ_CbPv| ,-ѳmEaM,Xb<]{˥_7Z*szw1(WKd>}yV E = )^. R#mm3rl/ʝndc=B!jGM<޺qkEO.u k1/E9n|jnMR%3SW産NjNd '@|[geH ^z= u`!h}B?<*ICǏhm"֨ "ꯦ-ߦM+͛dt CeGnITEMo=.02I[A 8^SID5Ӂ3#:k܆2Ɩ*K auD$e ֆ:Cvw] q?!`f3UL6oQJ h+ɹŢqJy'}μs\K6c-yG.J5!sWl r7 ず@_E͍^;`O!+G7*4៲(3Jp8'MpD=.q`cg|RPjMY өeg-$ˌdҍ N?L(*H rB)4BiplPU|ylcܬ{zȐ|)?jN(9Vp`16aϻtkEY<91[,4oM}:9Vű`&LCa(_E$!LP4׷aK3Ѻ@$( J[ Sj47Zԇ,x @Oe:$O] ^WԒ  ɀ MS÷Vfw,&Xl<9CZ F Gqo)LB:ʔdU3r xL vrࠊ$ s-2cyQ+o?3<9-|#ا~U=ed'k;2k7roՃBS#LodF©Ĕ2cSeWoz\]H>պ:Rn{@Zq(.G+܆BjT4y ~F q&\[a"ҝ̺HK [ 1&BgKLw?AVoNdS]mmtoЮ 8htz2(3*Ȉ_rIkF2ŘeRJiC.k&zG]?baGM؇pz\ױ_}M5Ux<fs(oe׀-5o"XWk$KzH d#ӠQq04P2Y\,qW`RWJp e'JeT5m'^ɇ ]ֻx-@dNum>ـ䂞h'e0X% ܽI?mw'\b ܾz= R(\: Xe. %w+Bh[[r+J˄XPEߗ8R%t?RǛQ DŽL^n'uc4Ui "kpDQcipG%% Fp81ش$O/ ˙VmMzfW;5ڱtCk*) wh lLo2-ZLlŲFF1{B!kw>,2.@r¯n :R̩GiO1FmJӫ.m`pc۷)>S w~ĔKT#橕5H1b4ImI㫐uW1+a L Ԋ-ϣ |dT'I^;K32'vTƞ6i7$IG`ٚq] tuizqF,'Cql4 |^ҋ*}\Co?Ry=}KCoޏ18b i68wK=I%q1.M&!JeMpbLEH V毰{Z6ʙ/ic.J%vQ46& +̊x"]QL{ؓۦ<r jP LEv$9k [HE~h_.ğ Kڑ*NyU@nI%>!$iEQ-crNmI ޠ䌄r{UOl+O] kRZ$][s[T@BBz*LcdB|@wW$oIU*ӝDj] lG0Suke +e_WrFTn;KFy:eepA*eމs9"'7P~7"$.&/`رH} Y..+b܂5xnDIs;]uH.dE}6o 7%MnwkA~(?G֯@k IrϮpi@II¸P`zəw/ *LCSɹS9 ;q% əcO{a@ /F2=k,AӉ svC(v( vyi-ovRfet\|hFy,"'GG&Ht3F}B$":8"9ϕ5ڗ{)j$Oֆz]48A GߒE&"4ᏓOgd. `L).G/6 H,JRJR:MNc`o!Q])i - g^kJu v҆kN-`ૄcfֵe\qL%[Ciϲ6C8#^Vć 3*JgP~vyP[ɌBzF4,~ilw@cY~MtOޝNhyD#i|qޚfzaN]W2sQ'vB?LH+&BlG&N]@1?3Gb m':iޠDٝi!%A:Z# {љTd|_mx="fo)^) &Dt O19ڦZ:oM^o ebӹ_.Z5-'=pTL-,Og ^knq*t rf}KYbq;,f w:'hkD766Rfmp՜nja mNiqcyvx[saCxoF 6~Pۻ=Pȭ; S?#n _ZtUwߩ7XL~Dj,eSw_y--r+GUYP<_& w[O((vӍIuY$-hm 3,{TXfs\'iZC>5WR<]ټh£B5Dٻ[R-gPNP?Q?83cH72WPo I@}9jˉΐ3 %\'V)a7E~~_{Qk?k}ۨ~ڏ~֟BڵN6ۂ^?jW'0[%k9y[{pUiۯW Sew^ۥDG43rerR ǔ#%{F%`9CVREjJB_E y,U)gLʘrZnYj(M⥇yb͖s7NZiNNxɛ&!x7^ֿJ)MqG Α/\Chq [6>w&Ӂ׊3g;Ѝ_;f7,D' &,,и]S`v|XnRA 1N<;w3pՂb%[kA"@_݂] ^T͠9|ːˋ؍z`,9E&Kqy5w > eHW5 H1s.W"E!`䡿42 h~P;7H0Asɗ;C߭C,0nu [9( 4[%Μ&6BjenW n _˧qT>Ud{%7U!ztq|aJŇ 7b#},jK-Ʀ\¹}t\o֫t Pu&;XZ[>TKvont鸻xs1p(!CBթ)+"ۊ(i EzOƚ7䱋MsOOKмS rdMP('О6ʚkw ٵqPFKЉ8U45X4zߎ`D4S+]{ЊQs fC7dc'Wa ;}đ,jTb CN*mV>3{ϓƯrXHa20`@ .TynFMc4fF Ftn G^ OHRrE<7sbE_Y39e.[r)%E?!Ȥy: N˟:Y/Qt[&J>vړ ? *d_ ެ\Gʰ'@~s]I)l~,c%5J[<Ax#$^w a˳WY`gV;x>ڨb(:{ +(RM^-Ko}`\8`-$fRx:t?i)H pIZ8~R$"He6~@BW5b\t5ʰ cv疬ɡpS~uP?W|h&@̨1ܚ" is>rlh\%gjiۯ"uRHa./W8ʣ=@H(!T}3t;y`nӼT?x  LmRr$S\+*O 2RՉ)uϝ{1}> iaڄ7y/qeaUD5.V;-Q꩎ 0PůIDWa'fG)|0cQOGR\ l[9t F[XQ^61G仍Br%߫y#<<>rȗE$|i by>nkDZױbY/e|QS7բ]݋#]i{-a[G2VqaDb,ce ՔȑCh؅mAn`!ɔ@օN9O~ .fSW}oǟfCn"5E9Xlb.C9Ҡgq([v'x2)rf0%F3#V%?Cx=tPxI zu9]MqI'XޝY)\F뵋?Vb%D8n@wŎ8͘ _7ȦØl!^៧%,S!ϩpְ/"=-_zQN Lʡ"A2҅b.!BZvطs( +H.2AeYl&o 7KFq\τSez5 ZESQu@p_l"%~ ^" >!YnnD<O11\4P#^鲃f1sS c.Viys#1.Ko-B"37S2vK-vJIT+Է<:C/B0%+2,ϻzf[-5,`&(NQEƧW5)}Nd7uq [/<3$ͦ$jӷԇ*q*u"ȩ1нn2SGauekZ#L.*%,cz?lq)QUxɕ{0E ]*)/~n*н謹JhM\%8pbTȲp2j|Ё,U̞yBpW)L&\~yM՜~?fr0Ɲudyq0Ikp,}ʲ;Ӧ{v>JH?i"׼XfPۀ: fOE47W7bɔs?&LfKR?#N~Ks~|llg&nlIQ ?זn8e OB*nz;b8'.Ι2brC}iTpxƊ_ĉnU=Wpj˄T7?u˛s<œ\BśpG2Xu='gn<:G?.S[ ~^մ諫zlb$ G=΋De>q'(/X=0GnPܪջ>uA,f$z U]E9Lh=gfoJ=0 o6CQѐR~{P,S { F\ܒ%=/TgP' ▃@NC\H  n~uO@rQ}e0>X DmkBK+U_ڬjӘ+Wֿ341{)#}YR^g`ăniG\>}O9[ %j6òvYM u+ 38’q{zk5s!X:g5#0E ~G"DX,54XԿ`~ӂ9̥Ü+"VH3i&MK(a's_^g` ӧJyI GZ_V2֜w"g =yS% g0~Oj a9Nv ROީJdo%%%?P5Es!tRs A# 1ZmTĦ؊tb0W ̟f$&L/`H锾kWb .!+gHIst.UX: `\@qtY}"n҅@ޅy3!۳8so1R'2;|7|?=u ֠0[D<܈ Vh}fȊW['Os(ra!6l2xP6񏋆Rn<0M=#˔g)D;0.MMW{煍4U NJ`.2'c*WBMcC"վǣ 6IGE@:x$h'+OJ#Z)I=XZji H QDƓHyZ)r 휕+g!ϑjiG*&; Yg__/Yc_Lz *~Hq g(6 C܏@ j%Q% 88:$,.$ezg;)QEKʻ}?.޲3 XcoQlinphone-desktop-4.2.5/linphone-app/cmake_builder/linphone_package/macos/linphone_dmg.scpt.in000077500000000000000000000023501376717241300325370ustar00rootroot00000000000000on run argv set image_name to item 1 of argv tell application "Finder" tell disk image_name -- open the image the first time and save a DS_Store with just -- background and icon setup open set current view of container window to icon view set theViewOptions to the icon view options of container window set background picture of theViewOptions to file ".background:background.jpg" set arrangement of theViewOptions to not arranged set icon size of theViewOptions to 100 delay 1 close -- next setup the position of the app and Applications symlink -- plus hide all the window decoration open update without registering applications tell container window set sidebar width to 0 set statusbar visible to false set toolbar visible to false set the bounds to { 300, 100, 1000, 520 } set position of item "@APPLICATION_NAME@.app" to { 200, 280 } set position of item "Applications" to { 500, 280 } end tell update without registering applications delay 1 close -- one last open and close so you can see everything looks correct open delay 5 close end tell delay 1 end tell end run linphone-desktop-4.2.5/linphone-app/cmake_builder/linphone_package/packaging.cmake.in000066400000000000000000000075431376717241300310330ustar00rootroot00000000000000############################################################################ # packaging.cmake # Copyright (C) 2017-2018 Belledonne Communications, Grenoble France # ############################################################################ # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # ############################################################################ set(DO_TGZ @CPACK_BINARY_TGZ@) set(DO_TZ @CPACK_BINARY_TZ@) set(DO_STGZ @CPACK_BINARY_STGZ@) set(DO_DRAGNDROP @CPACK_BINARY_DRAGNDROP@) set(DO_GENERATOR @DO_GENERATOR@) set(DO_APPIMAGE @DO_APPIMAGE@) if (NOT "${CMAKE_INSTALL_PREFIX}" MATCHES .*/_CPack_Packages/.*) if(DO_TGZ) execute_process( COMMAND ${CMAKE_CPACK_COMMAND} -G TGZ RESULT_VARIABLE CPACK_COMMAND_RESULT) if(CPACK_COMMAND_RESULT) message(FATAL_ERROR "Failed to create TGZ package!") endif() endif() if(DO_TZ) execute_process( COMMAND ${CMAKE_CPACK_COMMAND} -G TZ RESULT_VARIABLE CPACK_COMMAND_RESULT) if(CPACK_COMMAND_RESULT) message(FATAL_ERROR "Failed to create TZ package!") endif() endif() if(DO_STGZ) execute_process( COMMAND ${CMAKE_CPACK_COMMAND} -G STGZ RESULT_VARIABLE CPACK_COMMAND_RESULT) if(CPACK_COMMAND_RESULT) message(FATAL_ERROR "Failed to create STGZ package!") endif() endif() if(DO_DRAGNDROP) execute_process( COMMAND ${CMAKE_CPACK_COMMAND} -G DragNDrop RESULT_VARIABLE CPACK_COMMAND_RESULT) if(CPACK_COMMAND_RESULT) message(FATAL_ERROR "Failed to create DragAndDrop package!") endif() endif() if(DO_GENERATOR) execute_process( COMMAND ${CMAKE_CPACK_COMMAND} -G @CPACK_GENERATOR@ RESULT_VARIABLE CPACK_COMMAND_RESULT) if(CPACK_COMMAND_RESULT) message(FATAL_ERROR "Failed to create @CPACK_GENERATOR@ package!") endif() endif() if(DO_APPIMAGE) set(ENV QML_SOURCES_PATHS="@QML_SOURCES_PATHS@") set(ENV QML_MODULES_PATHS="@QML_MODULES_PATHS@") execute_process( COMMAND mkdir -p "WORK/Packages/AppImageDir/" WORKING_DIRECTORY "@CMAKE_INSTALL_PREFIX@/..") execute_process( COMMAND cp -rf "@CMAKE_CURRENT_SOURCE_DIR@/../../ui" "WORK/Packages/AppImageDir/" WORKING_DIRECTORY "@CMAKE_INSTALL_PREFIX@/..") execute_process( COMMAND "@CMAKE_CURRENT_SOURCE_DIR@/../../tools/create_appimage.sh" @CPACK_PACKAGE_FILE_NAME@ @LINPHONE_BUILDER_SIGNING_IDENTITY@ @LINPHONE_BUILDER_SIGNING_PASSPHRASE@ RESULT_VARIABLE CPACK_COMMAND_RESULT WORKING_DIRECTORY "@CMAKE_INSTALL_PREFIX@/.." ) if(CPACK_COMMAND_RESULT) message(FATAL_ERROR "Failed to create AppImage package with this command : '@CMAKE_CURRENT_SOURCE_DIR@/../../tools/create_appimage.sh @APP_PROJECT_VERSION@' at @CMAKE_INSTALL_PREFIX@/..\nMaybe the .appimage already exists and is running. Please remove the file before packaging if it is the case.") endif() endif() if (@PERFORM_SIGNING@) execute_process( COMMAND "@CMAKE_CURRENT_SOURCE_DIR@/../../tools/sign_package.bat" "@PASSPHRASE_FILE@" "@SIGNTOOL_COMMAND@" "@PFX_FILE@" "@TIMESTAMP_URL@" @CPACK_PACKAGE_FILE_NAME@.@PACKAGE_EXT@ RESULT_VARIABLE SIGNING_RESULT WORKING_DIRECTORY "@CPACK_PACKAGE_DIRECTORY@" ) if(SIGNING_RESULT) message(FATAL_ERROR "Failed to sign the package! ${SIGNING_RESULT} ${RESULT_VARIABLE}") endif() endif () endif () linphone-desktop-4.2.5/linphone-app/cmake_builder/linphone_package/sdk_content/000077500000000000000000000000001376717241300300025ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/cmake_builder/linphone_package/sdk_content/antlr3c.list.in000066400000000000000000000000461376717241300326520ustar00rootroot00000000000000@LIBDIR@/@LIBPREFIX@antlr3c*.@LIBEXT@ linphone-desktop-4.2.5/linphone-app/cmake_builder/linphone_package/sdk_content/bctoolbox.list.in000066400000000000000000000002031376717241300332720ustar00rootroot00000000000000@LIBDIR@/@LIBPREFIX@bctoolbox*.@LIBEXT@ include/bctoolbox/* lib/bctoolbox*.lib lib/pkgconfig/bctoolbox*.pc share/bctoolbox/cmake/* linphone-desktop-4.2.5/linphone-app/cmake_builder/linphone_package/sdk_content/bcunit.list.in000066400000000000000000000000441376717241300325660ustar00rootroot00000000000000@LIBDIR@/@LIBPREFIX@bcunit*.@LIBEXT@linphone-desktop-4.2.5/linphone-app/cmake_builder/linphone_package/sdk_content/bellesip.list.in000066400000000000000000000001771376717241300331100ustar00rootroot00000000000000@LIBDIR@/@LIBPREFIX@bellesip*.@LIBEXT@ include/belle-sip/* lib/bellesip*.lib lib/pkgconfig/belle-sip.pc share/BelleSIP/cmake/* linphone-desktop-4.2.5/linphone-app/cmake_builder/linphone_package/sdk_content/bv16.list.in000066400000000000000000000000421376717241300320560ustar00rootroot00000000000000@LIBDIR@/@LIBPREFIX@bv16*.@LIBEXT@linphone-desktop-4.2.5/linphone-app/cmake_builder/linphone_package/sdk_content/bzrtp.list.in000066400000000000000000000000661376717241300324470ustar00rootroot00000000000000@LIBDIR@/@LIBPREFIX@bzrtp*.@LIBEXT@ share/bzrtp/cmake linphone-desktop-4.2.5/linphone-app/cmake_builder/linphone_package/sdk_content/ffmpeg.list.in000066400000000000000000000002321376717241300325450ustar00rootroot00000000000000@LIBDIR@/@LIBPREFIX@avcodec*.@LIBEXT@ @LIBDIR@/@LIBPREFIX@avutil*.@LIBEXT@ @LIBDIR@/@LIBPREFIX@swscale*.@LIBEXT@ @LIBDIR@/@LIBPREFIX@swresample*.@LIBEXT@ linphone-desktop-4.2.5/linphone-app/cmake_builder/linphone_package/sdk_content/gsm.list.in000066400000000000000000000000411376717241300320650ustar00rootroot00000000000000@LIBDIR@/@LIBPREFIX@gsm*.@LIBEXT@linphone-desktop-4.2.5/linphone-app/cmake_builder/linphone_package/sdk_content/linphone.list.in000066400000000000000000000002201376717241300331120ustar00rootroot00000000000000@LIBDIR@/@LIBPREFIX@linphone*.@LIBEXT@ include/linphone/* lib/linphone*.lib share/doc/linphone-* share/Linphone/cmake/* share/sounds/linphone/* linphone-desktop-4.2.5/linphone-app/cmake_builder/linphone_package/sdk_content/linphonecxx.list.in000066400000000000000000000001551376717241300336440ustar00rootroot00000000000000@LIBDIR@/@LIBPREFIX@linphone*.@LIBEXT@ include/linphone++/* share/doc/linphoneCxx-* share/LinphoneCxx/cmake/*linphone-desktop-4.2.5/linphone-app/cmake_builder/linphone_package/sdk_content/mbedtls.list.in000066400000000000000000000001661376717241300327410ustar00rootroot00000000000000@LIBDIR@/@LIBPREFIX@mbedcrypto*.@LIBEXT@ @LIBDIR@/@LIBPREFIX@mbedx509*.@LIBEXT@ @LIBDIR@/@LIBPREFIX@mbedtls*.@LIBEXT@ linphone-desktop-4.2.5/linphone-app/cmake_builder/linphone_package/sdk_content/ms2.list.in000066400000000000000000000004101376717241300320000ustar00rootroot00000000000000@LIBDIR@/@LIBPREFIX@mediastreamer_base*.@LIBEXT@ @LIBDIR@/@LIBPREFIX@mediastreamer_voip*.@LIBEXT@ include/mediastreamer2/* lib/mediastreamer_base*.lib lib/mediastreamer_voip*.lib share/doc/mediastreamer2-* share/images/nowebcamCIF.jpg share/Mediastreamer2/cmake/* linphone-desktop-4.2.5/linphone-app/cmake_builder/linphone_package/sdk_content/ms2plugins.list.in000066400000000000000000000000501376717241300334020ustar00rootroot00000000000000lib/mediastreamer/plugins/*.@PLUGINEXT@ linphone-desktop-4.2.5/linphone-app/cmake_builder/linphone_package/sdk_content/opus.list.in000066400000000000000000000000421376717241300322660ustar00rootroot00000000000000@LIBDIR@/@LIBPREFIX@opus*.@LIBEXT@linphone-desktop-4.2.5/linphone-app/cmake_builder/linphone_package/sdk_content/ortp.list.in000066400000000000000000000001721376717241300322700ustar00rootroot00000000000000@LIBDIR@/@LIBPREFIX@ortp*.@LIBEXT@ include/ortp/* lib/ortp*.lib lib/pkgconfig/ortp.pc share/doc/oRTP-* share/oRTP/cmake/* linphone-desktop-4.2.5/linphone-app/cmake_builder/linphone_package/sdk_content/polarssl.list.in000066400000000000000000000000471376717241300331440ustar00rootroot00000000000000@LIBDIR@/@LIBPREFIX@polarssl*.@LIBEXT@ linphone-desktop-4.2.5/linphone-app/cmake_builder/linphone_package/sdk_content/speex.list.in000066400000000000000000000000431376717241300324250ustar00rootroot00000000000000@LIBDIR@/@LIBPREFIX@speex*.@LIBEXT@linphone-desktop-4.2.5/linphone-app/cmake_builder/linphone_package/sdk_content/sqlite3.list.in000066400000000000000000000000461376717241300326700ustar00rootroot00000000000000@LIBDIR@/@LIBPREFIX@sqlite3*.@LIBEXT@ linphone-desktop-4.2.5/linphone-app/cmake_builder/linphone_package/sdk_content/srtp.list.in000066400000000000000000000000421376717241300322700ustar00rootroot00000000000000@LIBDIR@/@LIBPREFIX@srtp*.@LIBEXT@linphone-desktop-4.2.5/linphone-app/cmake_builder/linphone_package/sdk_content/vcard.list.in000066400000000000000000000002151376717241300324010ustar00rootroot00000000000000@LIBDIR@/@LIBPREFIX@belr*.@LIBEXT@ @LIBDIR@/@LIBPREFIX@belcard*.@LIBEXT@ lib/belr*.lib lib/belcard*.lib share/Belr/cmake share/Belcard/cmake linphone-desktop-4.2.5/linphone-app/cmake_builder/linphone_package/sdk_content/xml2.list.in000066400000000000000000000000421376717241300321620ustar00rootroot00000000000000@LIBDIR@/@LIBPREFIX@xml2*.@LIBEXT@linphone-desktop-4.2.5/linphone-app/cmake_builder/linphone_package/sdk_content/zlib.list.in000066400000000000000000000000421376717241300322400ustar00rootroot00000000000000@LIBDIR@/@LIBPREFIX@zlib*.@LIBEXT@linphone-desktop-4.2.5/linphone-app/cmake_builder/linphone_package/windows/000077500000000000000000000000001376717241300271615ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/cmake_builder/linphone_package/windows/NSIS.template.in000066400000000000000000000700621376717241300321040ustar00rootroot00000000000000; CPack install script designed for a nmake build ;-------------------------------- ; You must define these values !define VERSION "@CPACK_PACKAGE_VERSION@" !define PATCH "@CPACK_PACKAGE_VERSION_PATCH@" !define INST_DIR "@CPACK_TEMPORARY_DIRECTORY@" ;-------------------------------- ;Variables Var MUI_TEMP Var STARTMENU_FOLDER Var SV_ALLUSERS Var START_MENU Var DO_NOT_ADD_TO_PATH Var ADD_TO_PATH_ALL_USERS Var ADD_TO_PATH_CURRENT_USER Var INSTALL_DESKTOP Var IS_DEFAULT_INSTALLDIR ;-------------------------------- ;Include Modern UI !include "MUI.nsh" ;Default installation folder InstallDir "@CPACK_NSIS_INSTALL_ROOT@\@CPACK_PACKAGE_INSTALL_DIRECTORY@" ;-------------------------------- ;General ;Name and file Name "@CPACK_NSIS_PACKAGE_NAME@" OutFile "@CPACK_TOPLEVEL_DIRECTORY@/@CPACK_OUTPUT_FILE_NAME@" ;Set compression SetCompressor @CPACK_NSIS_COMPRESSOR@ ;Require administrator access RequestExecutionLevel admin @CPACK_NSIS_DEFINES@ !include Sections.nsh ;--- Component support macros: --- ; The code for the add/remove functionality is from: ; http://nsis.sourceforge.net/Add/Remove_Functionality ; It has been modified slightly and extended to provide ; inter-component dependencies. Var AR_SecFlags Var AR_RegFlags @CPACK_NSIS_SECTION_SELECTED_VARS@ ; Loads the "selected" flag for the section named SecName into the ; variable VarName. !macro LoadSectionSelectedIntoVar SecName VarName SectionGetFlags ${${SecName}} $${VarName} IntOp $${VarName} $${VarName} & ${SF_SELECTED} ;Turn off all other bits !macroend ; Loads the value of a variable... can we get around this? !macro LoadVar VarName IntOp $R0 0 + $${VarName} !macroend ; Sets the value of a variable !macro StoreVar VarName IntValue IntOp $${VarName} 0 + ${IntValue} !macroend !macro InitSection SecName ; This macro reads component installed flag from the registry and ;changes checked state of the section on the components page. ;Input: section index constant name specified in Section command. ClearErrors ;Reading component status from registry ReadRegDWORD $AR_RegFlags HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@\Components\${SecName}" "Installed" IfErrors "default_${SecName}" ;Status will stay default if registry value not found ;(component was never installed) IntOp $AR_RegFlags $AR_RegFlags & ${SF_SELECTED} ;Turn off all other bits SectionGetFlags ${${SecName}} $AR_SecFlags ;Reading default section flags IntOp $AR_SecFlags $AR_SecFlags & 0xFFFE ;Turn lowest (enabled) bit off IntOp $AR_SecFlags $AR_RegFlags | $AR_SecFlags ;Change lowest bit ; Note whether this component was installed before !insertmacro StoreVar ${SecName}_was_installed $AR_RegFlags IntOp $R0 $AR_RegFlags & $AR_RegFlags ;Writing modified flags SectionSetFlags ${${SecName}} $AR_SecFlags "default_${SecName}:" !insertmacro LoadSectionSelectedIntoVar ${SecName} ${SecName}_selected !macroend !macro FinishSection SecName ; This macro reads section flag set by user and removes the section ;if it is not selected. ;Then it writes component installed flag to registry ;Input: section index constant name specified in Section command. SectionGetFlags ${${SecName}} $AR_SecFlags ;Reading section flags ;Checking lowest bit: IntOp $AR_SecFlags $AR_SecFlags & ${SF_SELECTED} IntCmp $AR_SecFlags 1 "leave_${SecName}" ;Section is not selected: ;Calling Section uninstall macro and writing zero installed flag !insertmacro "Remove_${${SecName}}" WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@\Components\${SecName}" \ "Installed" 0 Goto "exit_${SecName}" "leave_${SecName}:" ;Section is selected: WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@\Components\${SecName}" \ "Installed" 1 "exit_${SecName}:" !macroend !macro RemoveSection_CPack SecName ; This macro is used to call section's Remove_... macro ;from the uninstaller. ;Input: section index constant name specified in Section command. !insertmacro "Remove_${${SecName}}" !macroend ; Determine whether the selection of SecName changed !macro MaybeSelectionChanged SecName !insertmacro LoadVar ${SecName}_selected SectionGetFlags ${${SecName}} $R1 IntOp $R1 $R1 & ${SF_SELECTED} ;Turn off all other bits ; See if the status has changed: IntCmp $R0 $R1 "${SecName}_unchanged" !insertmacro LoadSectionSelectedIntoVar ${SecName} ${SecName}_selected IntCmp $R1 ${SF_SELECTED} "${SecName}_was_selected" !insertmacro "Deselect_required_by_${SecName}" goto "${SecName}_unchanged" "${SecName}_was_selected:" !insertmacro "Select_${SecName}_depends" "${SecName}_unchanged:" !macroend ;--- End of Add/Remove macros --- ;-------------------------------- ;Interface Settings !define MUI_HEADERIMAGE !define MUI_ABORTWARNING ;-------------------------------- ; path functions !verbose 3 !include "WinMessages.NSH" !verbose 4 ;---------------------------------------- ; based upon a script of "Written by KiCHiK 2003-01-18 05:57:02" ;---------------------------------------- !verbose 3 !include "WinMessages.NSH" !verbose 4 ;==================================================== ; get_NT_environment ; Returns: the selected environment ; Output : head of the stack ;==================================================== !macro select_NT_profile UN Function ${UN}select_NT_profile StrCmp $ADD_TO_PATH_ALL_USERS "1" 0 environment_single DetailPrint "Selected environment for all users" Push "all" Return environment_single: DetailPrint "Selected environment for current user only." Push "current" Return FunctionEnd !macroend !insertmacro select_NT_profile "" !insertmacro select_NT_profile "un." ;---------------------------------------------------- !define NT_current_env 'HKCU "Environment"' !define NT_all_env 'HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"' !ifndef WriteEnvStr_RegKey !ifdef ALL_USERS !define WriteEnvStr_RegKey \ 'HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"' !else !define WriteEnvStr_RegKey 'HKCU "Environment"' !endif !endif ; AddToPath - Adds the given dir to the search path. ; Input - head of the stack ; Note - Win9x systems requires reboot Function AddToPath Exch $0 Push $1 Push $2 Push $3 # don't add if the path doesn't exist IfFileExists "$0\*.*" "" AddToPath_done ReadEnvStr $1 PATH ; if the path is too long for a NSIS variable NSIS will return a 0 ; length string. If we find that, then warn and skip any path ; modification as it will trash the existing path. StrLen $2 $1 IntCmp $2 0 CheckPathLength_ShowPathWarning CheckPathLength_Done CheckPathLength_Done CheckPathLength_ShowPathWarning: Messagebox MB_OK|MB_ICONEXCLAMATION "Warning! PATH too long installer unable to modify PATH!" Goto AddToPath_done CheckPathLength_Done: Push "$1;" Push "$0;" Call StrStr Pop $2 StrCmp $2 "" "" AddToPath_done Push "$1;" Push "$0\;" Call StrStr Pop $2 StrCmp $2 "" "" AddToPath_done GetFullPathName /SHORT $3 $0 Push "$1;" Push "$3;" Call StrStr Pop $2 StrCmp $2 "" "" AddToPath_done Push "$1;" Push "$3\;" Call StrStr Pop $2 StrCmp $2 "" "" AddToPath_done Call IsNT Pop $1 StrCmp $1 1 AddToPath_NT ; Not on NT StrCpy $1 $WINDIR 2 FileOpen $1 "$1\autoexec.bat" a FileSeek $1 -1 END FileReadByte $1 $2 IntCmp $2 26 0 +2 +2 # DOS EOF FileSeek $1 -1 END # write over EOF FileWrite $1 "$\r$\nSET PATH=%PATH%;$3$\r$\n" FileClose $1 SetRebootFlag true Goto AddToPath_done AddToPath_NT: StrCmp $ADD_TO_PATH_ALL_USERS "1" ReadAllKey ReadRegStr $1 ${NT_current_env} "PATH" Goto DoTrim ReadAllKey: ReadRegStr $1 ${NT_all_env} "PATH" DoTrim: StrCmp $1 "" AddToPath_NTdoIt Push $1 Call Trim Pop $1 StrCpy $0 "$1;$0" AddToPath_NTdoIt: StrCmp $ADD_TO_PATH_ALL_USERS "1" WriteAllKey WriteRegExpandStr ${NT_current_env} "PATH" $0 Goto DoSend WriteAllKey: WriteRegExpandStr ${NT_all_env} "PATH" $0 DoSend: SendMessage ${HWND_BROADCAST} ${WM_WININICHANGE} 0 "STR:Environment" /TIMEOUT=5000 AddToPath_done: Pop $3 Pop $2 Pop $1 Pop $0 FunctionEnd ; RemoveFromPath - Remove a given dir from the path ; Input: head of the stack Function un.RemoveFromPath Exch $0 Push $1 Push $2 Push $3 Push $4 Push $5 Push $6 IntFmt $6 "%c" 26 # DOS EOF Call un.IsNT Pop $1 StrCmp $1 1 unRemoveFromPath_NT ; Not on NT StrCpy $1 $WINDIR 2 FileOpen $1 "$1\autoexec.bat" r GetTempFileName $4 FileOpen $2 $4 w GetFullPathName /SHORT $0 $0 StrCpy $0 "SET PATH=%PATH%;$0" Goto unRemoveFromPath_dosLoop unRemoveFromPath_dosLoop: FileRead $1 $3 StrCpy $5 $3 1 -1 # read last char StrCmp $5 $6 0 +2 # if DOS EOF StrCpy $3 $3 -1 # remove DOS EOF so we can compare StrCmp $3 "$0$\r$\n" unRemoveFromPath_dosLoopRemoveLine StrCmp $3 "$0$\n" unRemoveFromPath_dosLoopRemoveLine StrCmp $3 "$0" unRemoveFromPath_dosLoopRemoveLine StrCmp $3 "" unRemoveFromPath_dosLoopEnd FileWrite $2 $3 Goto unRemoveFromPath_dosLoop unRemoveFromPath_dosLoopRemoveLine: SetRebootFlag true Goto unRemoveFromPath_dosLoop unRemoveFromPath_dosLoopEnd: FileClose $2 FileClose $1 StrCpy $1 $WINDIR 2 Delete "$1\autoexec.bat" CopyFiles /SILENT $4 "$1\autoexec.bat" Delete $4 Goto unRemoveFromPath_done unRemoveFromPath_NT: StrCmp $ADD_TO_PATH_ALL_USERS "1" unReadAllKey ReadRegStr $1 ${NT_current_env} "PATH" Goto unDoTrim unReadAllKey: ReadRegStr $1 ${NT_all_env} "PATH" unDoTrim: StrCpy $5 $1 1 -1 # copy last char StrCmp $5 ";" +2 # if last char != ; StrCpy $1 "$1;" # append ; Push $1 Push "$0;" Call un.StrStr ; Find `$0;` in $1 Pop $2 ; pos of our dir StrCmp $2 "" unRemoveFromPath_done ; else, it is in path # $0 - path to add # $1 - path var StrLen $3 "$0;" StrLen $4 $2 StrCpy $5 $1 -$4 # $5 is now the part before the path to remove StrCpy $6 $2 "" $3 # $6 is now the part after the path to remove StrCpy $3 $5$6 StrCpy $5 $3 1 -1 # copy last char StrCmp $5 ";" 0 +2 # if last char == ; StrCpy $3 $3 -1 # remove last char StrCmp $ADD_TO_PATH_ALL_USERS "1" unWriteAllKey WriteRegExpandStr ${NT_current_env} "PATH" $3 Goto unDoSend unWriteAllKey: WriteRegExpandStr ${NT_all_env} "PATH" $3 unDoSend: SendMessage ${HWND_BROADCAST} ${WM_WININICHANGE} 0 "STR:Environment" /TIMEOUT=5000 unRemoveFromPath_done: Pop $6 Pop $5 Pop $4 Pop $3 Pop $2 Pop $1 Pop $0 FunctionEnd ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Uninstall sutff ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ########################################### # Utility Functions # ########################################### ;==================================================== ; IsNT - Returns 1 if the current system is NT, 0 ; otherwise. ; Output: head of the stack ;==================================================== ; IsNT ; no input ; output, top of the stack = 1 if NT or 0 if not ; ; Usage: ; Call IsNT ; Pop $R0 ; ($R0 at this point is 1 or 0) !macro IsNT un Function ${un}IsNT Push $0 ReadRegStr $0 HKLM "SOFTWARE\Microsoft\Windows NT\CurrentVersion" CurrentVersion StrCmp $0 "" 0 IsNT_yes ; we are not NT. Pop $0 Push 0 Return IsNT_yes: ; NT!!! Pop $0 Push 1 FunctionEnd !macroend !insertmacro IsNT "" !insertmacro IsNT "un." ; StrStr ; input, top of stack = string to search for ; top of stack-1 = string to search in ; output, top of stack (replaces with the portion of the string remaining) ; modifies no other variables. ; ; Usage: ; Push "this is a long ass string" ; Push "ass" ; Call StrStr ; Pop $R0 ; ($R0 at this point is "ass string") !macro StrStr un Function ${un}StrStr Exch $R1 ; st=haystack,old$R1, $R1=needle Exch ; st=old$R1,haystack Exch $R2 ; st=old$R1,old$R2, $R2=haystack Push $R3 Push $R4 Push $R5 StrLen $R3 $R1 StrCpy $R4 0 ; $R1=needle ; $R2=haystack ; $R3=len(needle) ; $R4=cnt ; $R5=tmp loop: StrCpy $R5 $R2 $R3 $R4 StrCmp $R5 $R1 done StrCmp $R5 "" done IntOp $R4 $R4 + 1 Goto loop done: StrCpy $R1 $R2 "" $R4 Pop $R5 Pop $R4 Pop $R3 Pop $R2 Exch $R1 FunctionEnd !macroend !insertmacro StrStr "" !insertmacro StrStr "un." Function Trim ; Added by Pelaca Exch $R1 Push $R2 Loop: StrCpy $R2 "$R1" 1 -1 StrCmp "$R2" " " RTrim StrCmp "$R2" "$\n" RTrim StrCmp "$R2" "$\r" RTrim StrCmp "$R2" ";" RTrim GoTo Done RTrim: StrCpy $R1 "$R1" -1 Goto Loop Done: Pop $R2 Exch $R1 FunctionEnd Function ConditionalAddToRegisty Pop $0 Pop $1 StrCmp "$0" "" ConditionalAddToRegisty_EmptyString WriteRegStr SHCTX "Software\Microsoft\Windows\CurrentVersion\Uninstall\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@" \ "$1" "$0" ;MessageBox MB_OK "Set Registry: '$1' to '$0'" DetailPrint "Set install registry entry: '$1' to '$0'" ConditionalAddToRegisty_EmptyString: FunctionEnd ;-------------------------------- !ifdef CPACK_USES_DOWNLOAD Function DownloadFile IfFileExists $INSTDIR\* +2 CreateDirectory $INSTDIR Pop $0 ; Skip if already downloaded IfFileExists $INSTDIR\$0 0 +2 Return StrCpy $1 "@CPACK_DOWNLOAD_SITE@" try_again: NSISdl::download "$1/$0" "$INSTDIR\$0" Pop $1 StrCmp $1 "success" success StrCmp $1 "Cancelled" cancel MessageBox MB_OK "Download failed: $1" cancel: Return success: FunctionEnd !endif ;-------------------------------- ; Installation types @CPACK_NSIS_INSTALLATION_TYPES@ ;-------------------------------- ; Component sections @CPACK_NSIS_COMPONENT_SECTIONS@ ;-------------------------------- ; Define some macro setting for the gui @CPACK_NSIS_INSTALLER_MUI_ICON_CODE@ @CPACK_NSIS_INSTALLER_ICON_CODE@ @CPACK_NSIS_INSTALLER_MUI_COMPONENTS_DESC@ @CPACK_NSIS_INSTALLER_MUI_FINISHPAGE_RUN_CODE@ ;-------------------------------- ;Pages !insertmacro MUI_PAGE_WELCOME !insertmacro MUI_PAGE_LICENSE "@CPACK_RESOURCE_FILE_LICENSE@" Page custom InstallOptionsPage !insertmacro MUI_PAGE_DIRECTORY ;Start Menu Folder Page Configuration !define MUI_STARTMENUPAGE_REGISTRY_ROOT "SHCTX" !define MUI_STARTMENUPAGE_REGISTRY_KEY "Software\@CPACK_PACKAGE_VENDOR@\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@" !define MUI_STARTMENUPAGE_REGISTRY_VALUENAME "Start Menu Folder" !insertmacro MUI_PAGE_STARTMENU Application $STARTMENU_FOLDER @CPACK_NSIS_PAGE_COMPONENTS@ !insertmacro MUI_PAGE_INSTFILES !insertmacro MUI_PAGE_FINISH !insertmacro MUI_UNPAGE_CONFIRM !insertmacro MUI_UNPAGE_INSTFILES ;-------------------------------- ;Languages !insertmacro MUI_LANGUAGE "English" ;first language is the default language !insertmacro MUI_LANGUAGE "Albanian" !insertmacro MUI_LANGUAGE "Arabic" !insertmacro MUI_LANGUAGE "Basque" !insertmacro MUI_LANGUAGE "Belarusian" !insertmacro MUI_LANGUAGE "Bosnian" !insertmacro MUI_LANGUAGE "Breton" !insertmacro MUI_LANGUAGE "Bulgarian" !insertmacro MUI_LANGUAGE "Croatian" !insertmacro MUI_LANGUAGE "Czech" !insertmacro MUI_LANGUAGE "Danish" !insertmacro MUI_LANGUAGE "Dutch" !insertmacro MUI_LANGUAGE "Estonian" !insertmacro MUI_LANGUAGE "Farsi" !insertmacro MUI_LANGUAGE "Finnish" !insertmacro MUI_LANGUAGE "French" !insertmacro MUI_LANGUAGE "German" !insertmacro MUI_LANGUAGE "Greek" !insertmacro MUI_LANGUAGE "Hebrew" !insertmacro MUI_LANGUAGE "Hungarian" !insertmacro MUI_LANGUAGE "Icelandic" !insertmacro MUI_LANGUAGE "Indonesian" !insertmacro MUI_LANGUAGE "Irish" !insertmacro MUI_LANGUAGE "Italian" !insertmacro MUI_LANGUAGE "Japanese" !insertmacro MUI_LANGUAGE "Korean" !insertmacro MUI_LANGUAGE "Kurdish" !insertmacro MUI_LANGUAGE "Latvian" !insertmacro MUI_LANGUAGE "Lithuanian" !insertmacro MUI_LANGUAGE "Luxembourgish" !insertmacro MUI_LANGUAGE "Macedonian" !insertmacro MUI_LANGUAGE "Malay" !insertmacro MUI_LANGUAGE "Mongolian" !insertmacro MUI_LANGUAGE "Norwegian" !insertmacro MUI_LANGUAGE "Polish" !insertmacro MUI_LANGUAGE "Portuguese" !insertmacro MUI_LANGUAGE "PortugueseBR" !insertmacro MUI_LANGUAGE "Romanian" !insertmacro MUI_LANGUAGE "Russian" !insertmacro MUI_LANGUAGE "Serbian" !insertmacro MUI_LANGUAGE "SerbianLatin" !insertmacro MUI_LANGUAGE "SimpChinese" !insertmacro MUI_LANGUAGE "Slovak" !insertmacro MUI_LANGUAGE "Slovenian" !insertmacro MUI_LANGUAGE "Spanish" !insertmacro MUI_LANGUAGE "Swedish" !insertmacro MUI_LANGUAGE "Thai" !insertmacro MUI_LANGUAGE "TradChinese" !insertmacro MUI_LANGUAGE "Turkish" !insertmacro MUI_LANGUAGE "Ukrainian" !insertmacro MUI_LANGUAGE "Welsh" ;-------------------------------- ;Reserve Files ;These files should be inserted before other files in the data block ;Keep these lines before any File command ;Only for solid compression (by default, solid compression is enabled for BZIP2 and LZMA) ReserveFile "NSIS.InstallOptions.ini" !insertmacro MUI_RESERVEFILE_INSTALLOPTIONS ;-------------------------------- ;Installer Sections Section "-Core installation" ;Use the entire tree produced by the INSTALL target. Keep the ;list of directories here in sync with the RMDir commands below. SetOutPath "$INSTDIR" @CPACK_NSIS_EXTRA_PREINSTALL_COMMANDS@ @CPACK_NSIS_FULL_INSTALL@ ;Store installation folder WriteRegStr SHCTX "Software\@CPACK_PACKAGE_VENDOR@\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@" "" $INSTDIR ;Create uninstaller WriteUninstaller "$INSTDIR\Uninstall.exe" Push "DisplayName" Push "@CPACK_NSIS_DISPLAY_NAME@" Call ConditionalAddToRegisty Push "DisplayVersion" Push "@CPACK_PACKAGE_VERSION@" Call ConditionalAddToRegisty Push "Publisher" Push "@CPACK_PACKAGE_VENDOR@" Call ConditionalAddToRegisty Push "UninstallString" Push "$INSTDIR\Uninstall.exe" Call ConditionalAddToRegisty Push "NoRepair" Push "1" Call ConditionalAddToRegisty !ifdef CPACK_NSIS_ADD_REMOVE ;Create add/remove functionality Push "ModifyPath" Push "$INSTDIR\AddRemove.exe" Call ConditionalAddToRegisty !else Push "NoModify" Push "1" Call ConditionalAddToRegisty !endif ; Optional registration Push "DisplayIcon" Push "$INSTDIR\@CPACK_NSIS_INSTALLED_ICON_NAME@" Call ConditionalAddToRegisty Push "HelpLink" Push "@CPACK_NSIS_HELP_LINK@" Call ConditionalAddToRegisty Push "URLInfoAbout" Push "@CPACK_NSIS_URL_INFO_ABOUT@" Call ConditionalAddToRegisty Push "Contact" Push "@CPACK_NSIS_CONTACT@" Call ConditionalAddToRegisty !insertmacro MUI_INSTALLOPTIONS_READ $INSTALL_DESKTOP "NSIS.InstallOptions.ini" "Field 5" "State" !insertmacro MUI_STARTMENU_WRITE_BEGIN Application ;Create shortcuts CreateDirectory "$SMPROGRAMS\$STARTMENU_FOLDER" @CPACK_NSIS_CREATE_ICONS@ @CPACK_NSIS_CREATE_ICONS_EXTRA@ CreateShortCut "$SMPROGRAMS\$STARTMENU_FOLDER\Uninstall.lnk" "$INSTDIR\Uninstall.exe" ;Read a value from an InstallOptions INI file !insertmacro MUI_INSTALLOPTIONS_READ $DO_NOT_ADD_TO_PATH "NSIS.InstallOptions.ini" "Field 2" "State" !insertmacro MUI_INSTALLOPTIONS_READ $ADD_TO_PATH_ALL_USERS "NSIS.InstallOptions.ini" "Field 3" "State" !insertmacro MUI_INSTALLOPTIONS_READ $ADD_TO_PATH_CURRENT_USER "NSIS.InstallOptions.ini" "Field 4" "State" ; Write special uninstall registry entries Push "StartMenu" Push "$STARTMENU_FOLDER" Call ConditionalAddToRegisty Push "DoNotAddToPath" Push "$DO_NOT_ADD_TO_PATH" Call ConditionalAddToRegisty Push "AddToPathAllUsers" Push "$ADD_TO_PATH_ALL_USERS" Call ConditionalAddToRegisty Push "AddToPathCurrentUser" Push "$ADD_TO_PATH_CURRENT_USER" Call ConditionalAddToRegisty Push "InstallToDesktop" Push "$INSTALL_DESKTOP" Call ConditionalAddToRegisty !insertmacro MUI_STARTMENU_WRITE_END @CPACK_NSIS_EXTRA_INSTALL_COMMANDS@ SectionEnd Section "-Add to path" Push $INSTDIR\bin StrCmp "@CPACK_NSIS_MODIFY_PATH@" "ON" 0 doNotAddToPath StrCmp $DO_NOT_ADD_TO_PATH "1" doNotAddToPath 0 Call AddToPath doNotAddToPath: SectionEnd ;-------------------------------- ; Create custom pages Function InstallOptionsPage !insertmacro MUI_HEADER_TEXT "Install Options" "Choose options for installing @CPACK_NSIS_PACKAGE_NAME@" !insertmacro MUI_INSTALLOPTIONS_DISPLAY "NSIS.InstallOptions.ini" FunctionEnd ;-------------------------------- ; determine admin versus local install Function un.onInit ClearErrors UserInfo::GetName IfErrors noLM Pop $0 UserInfo::GetAccountType Pop $1 StrCmp $1 "Admin" 0 +3 SetShellVarContext all ;MessageBox MB_OK 'User "$0" is in the Admin group' Goto done StrCmp $1 "Power" 0 +3 SetShellVarContext all ;MessageBox MB_OK 'User "$0" is in the Power Users group' Goto done noLM: ;Get installation folder from registry if available done: FunctionEnd ;--- Add/Remove callback functions: --- !macro SectionList MacroName ;This macro used to perform operation on multiple sections. ;List all of your components in following manner here. @CPACK_NSIS_COMPONENT_SECTION_LIST@ !macroend Section -FinishComponents ;Removes unselected components and writes component status to registry !insertmacro SectionList "FinishSection" !ifdef CPACK_NSIS_ADD_REMOVE ; Get the name of the installer executable System::Call 'kernel32::GetModuleFileNameA(i 0, t .R0, i 1024) i r1' StrCpy $R3 $R0 ; Strip off the last 13 characters, to see if we have AddRemove.exe StrLen $R1 $R0 IntOp $R1 $R0 - 13 StrCpy $R2 $R0 13 $R1 StrCmp $R2 "AddRemove.exe" addremove_installed ; We're not running AddRemove.exe, so install it CopyFiles $R3 $INSTDIR\AddRemove.exe addremove_installed: !endif SectionEnd ;--- End of Add/Remove callback functions --- ;-------------------------------- ; Component dependencies Function .onSelChange !insertmacro SectionList MaybeSelectionChanged FunctionEnd ;-------------------------------- ;Uninstaller Section Section "Uninstall" ReadRegStr $START_MENU SHCTX \ "Software\Microsoft\Windows\CurrentVersion\Uninstall\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@" "StartMenu" ;MessageBox MB_OK "Start menu is in: $START_MENU" ReadRegStr $DO_NOT_ADD_TO_PATH SHCTX \ "Software\Microsoft\Windows\CurrentVersion\Uninstall\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@" "DoNotAddToPath" ReadRegStr $ADD_TO_PATH_ALL_USERS SHCTX \ "Software\Microsoft\Windows\CurrentVersion\Uninstall\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@" "AddToPathAllUsers" ReadRegStr $ADD_TO_PATH_CURRENT_USER SHCTX \ "Software\Microsoft\Windows\CurrentVersion\Uninstall\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@" "AddToPathCurrentUser" ;MessageBox MB_OK "Add to path: $DO_NOT_ADD_TO_PATH all users: $ADD_TO_PATH_ALL_USERS" ReadRegStr $INSTALL_DESKTOP SHCTX \ "Software\Microsoft\Windows\CurrentVersion\Uninstall\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@" "InstallToDesktop" ;MessageBox MB_OK "Install to desktop: $INSTALL_DESKTOP " @CPACK_NSIS_EXTRA_UNINSTALL_COMMANDS@ ;Remove files we installed. ;Keep the list of directories here in sync with the File commands above. @CPACK_NSIS_DELETE_FILES@ @CPACK_NSIS_DELETE_DIRECTORIES@ !ifdef CPACK_NSIS_ADD_REMOVE ;Remove the add/remove program Delete "$INSTDIR\AddRemove.exe" !endif ;Remove the uninstaller itself. Delete "$INSTDIR\Uninstall.exe" DeleteRegKey SHCTX "Software\Microsoft\Windows\CurrentVersion\Uninstall\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@" ;Remove the installation directory if it is empty. RMDir "$INSTDIR" ; Remove the registry entries. DeleteRegKey SHCTX "Software\@CPACK_PACKAGE_VENDOR@\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@" ; Removes all optional components !insertmacro SectionList "RemoveSection_CPack" !insertmacro MUI_STARTMENU_GETFOLDER Application $MUI_TEMP Delete "$SMPROGRAMS\$MUI_TEMP\Uninstall.lnk" @CPACK_NSIS_DELETE_ICONS@ @CPACK_NSIS_DELETE_ICONS_EXTRA@ ;Delete empty start menu parent diretories StrCpy $MUI_TEMP "$SMPROGRAMS\$MUI_TEMP" startMenuDeleteLoop: ClearErrors RMDir $MUI_TEMP GetFullPathName $MUI_TEMP "$MUI_TEMP\.." IfErrors startMenuDeleteLoopDone StrCmp "$MUI_TEMP" "$SMPROGRAMS" startMenuDeleteLoopDone startMenuDeleteLoop startMenuDeleteLoopDone: ; If the user changed the shortcut, then untinstall may not work. This should ; try to fix it. StrCpy $MUI_TEMP "$START_MENU" Delete "$SMPROGRAMS\$MUI_TEMP\Uninstall.lnk" @CPACK_NSIS_DELETE_ICONS_EXTRA@ ;Delete empty start menu parent diretories StrCpy $MUI_TEMP "$SMPROGRAMS\$MUI_TEMP" secondStartMenuDeleteLoop: ClearErrors RMDir $MUI_TEMP GetFullPathName $MUI_TEMP "$MUI_TEMP\.." IfErrors secondStartMenuDeleteLoopDone StrCmp "$MUI_TEMP" "$SMPROGRAMS" secondStartMenuDeleteLoopDone secondStartMenuDeleteLoop secondStartMenuDeleteLoopDone: DeleteRegKey /ifempty SHCTX "Software\@CPACK_PACKAGE_VENDOR@\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@" Push $INSTDIR\bin StrCmp $DO_NOT_ADD_TO_PATH_ "1" doNotRemoveFromPath 0 Call un.RemoveFromPath doNotRemoveFromPath: SectionEnd ;-------------------------------- ; determine admin versus local install ; Is install for "AllUsers" or "JustMe"? ; Default to "JustMe" - set to "AllUsers" if admin or on Win9x ; This function is used for the very first "custom page" of the installer. ; This custom page does not show up visibly, but it executes prior to the ; first visible page and sets up $INSTDIR properly... ; Choose different default installation folder based on SV_ALLUSERS... ; "Program Files" for AllUsers, "My Documents" for JustMe... Function .onInit FindWindow $0 "gdkWindowToplevel" "@CPACK_PACKAGE_NAME@" FindWindow $1 "Qt5QWindowOwnDCIcon" "@CPACK_PACKAGE_NAME@" StrCmp "$0$1" "00" notRunning MessageBox MB_OK|MB_ICONEXCLAMATION "@CPACK_PACKAGE_NAME@ is running. Please close it first and restart the installation." /SD IDOK Abort notRunning: ReadRegStr $0 HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@" "UninstallString" StrCmp $0 "" inst MessageBox MB_OKCANCEL|MB_ICONEXCLAMATION \ "@CPACK_PACKAGE_NAME@ is already installed. $\n$\nDo you want to continue and uninstall the old version before installing the new one?" \ IDOK uninst Abort ;Run the uninstaller uninst: ClearErrors StrLen $2 "\Uninstall.exe" StrCpy $3 $0 -$2 # remove "\Uninstall.exe" from UninstallString to get path ExecWait '$0 _?=$3' ;Do not copy the uninstaller to a temp file IfErrors uninst_failed inst uninst_failed: MessageBox MB_OK|MB_ICONSTOP "Uninstall failed." Abort inst: ; Reads components status for registry !insertmacro SectionList "InitSection" ; check to see if /D has been used to change ; the install directory by comparing it to the ; install directory that is expected to be the ; default StrCpy $IS_DEFAULT_INSTALLDIR 0 StrCmp "$INSTDIR" "@CPACK_NSIS_INSTALL_ROOT@\@CPACK_PACKAGE_INSTALL_DIRECTORY@" 0 +2 StrCpy $IS_DEFAULT_INSTALLDIR 1 StrCpy $SV_ALLUSERS "JustMe" ; if default install dir then change the default ; if it is installed for JustMe StrCmp "$IS_DEFAULT_INSTALLDIR" "1" 0 +2 StrCpy $INSTDIR "$DOCUMENTS\@CPACK_PACKAGE_INSTALL_DIRECTORY@" ClearErrors UserInfo::GetName IfErrors noLM Pop $0 UserInfo::GetAccountType Pop $1 StrCmp $1 "Admin" 0 +4 SetShellVarContext all ;MessageBox MB_OK 'User "$0" is in the Admin group' StrCpy $SV_ALLUSERS "AllUsers" Goto done StrCmp $1 "Power" 0 +4 SetShellVarContext all ;MessageBox MB_OK 'User "$0" is in the Power Users group' StrCpy $SV_ALLUSERS "AllUsers" Goto done noLM: StrCpy $SV_ALLUSERS "AllUsers" ;Get installation folder from registry if available done: StrCmp $SV_ALLUSERS "AllUsers" 0 +3 StrCmp "$IS_DEFAULT_INSTALLDIR" "1" 0 +2 StrCpy $INSTDIR "@CPACK_NSIS_INSTALL_ROOT@\@CPACK_PACKAGE_INSTALL_DIRECTORY@" StrCmp "@CPACK_NSIS_MODIFY_PATH@" "ON" 0 noOptionsPage !insertmacro MUI_INSTALLOPTIONS_EXTRACT "NSIS.InstallOptions.ini" noOptionsPage: FunctionEnd linphone-desktop-4.2.5/linphone-app/cmake_builder/linphone_package/windows/appDetailsWindows.rc.in000066400000000000000000000024131376717241300335550ustar00rootroot00000000000000A ICON MOVEABLE PURE LOADONCALL DISCARDABLE "assets/icon.ico" # if defined(UNDER_CE) # include # else # include # endif VS_VERSION_INFO VERSIONINFO PRODUCTVERSION ${version_major},${version_minor},${version_patch},0 FILEVERSION ${version_major},${version_minor},${version_patch},0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS VS_FF_DEBUG #else FILEFLAGS 0x0L #endif FILEOS VOS__WINDOWS32 FILETYPE VFT_APP FILESUBTYPE 0x0L BEGIN BLOCK "StringFileInfo" BEGIN BLOCK "040904B0" BEGIN VALUE "CompanyName", "${APPLICATION_VENDOR}\0" VALUE "FileDescription", "${APPLICATION_NAME} - ${APPLICATION_DESCRIPTION}\0" VALUE "FileVersion", "${FULL_VERSION}" VALUE "ProductVersion", "${version_major}.${version_minor}.${version_patch}\0" VALUE "LegalCopyright", "Copyright (C) ${COPYRIGTH_RANGE_DATE} ${APPLICATION_VENDOR} ${APPLICATION_URL}\0" VALUE "OriginalFilename", "${EXECUTABLE_NAME}.exe\0" VALUE "ProductName", "${APPLICATION_NAME}\0" END END BLOCK "VarFileInfo" BEGIN VALUE "Translation", 0x409, 1200 END END /* End of Version info */ linphone-desktop-4.2.5/linphone-app/cmake_builder/linphone_package/windows/install.nsi.in000066400000000000000000000103371376717241300317530ustar00rootroot00000000000000 # Application details WriteRegStr HKLM "SOFTWARE\@APPLICATION_VENDOR@" "" "" WriteRegStr HKLM "SOFTWARE\@APPLICATION_VENDOR@\@APPLICATION_NAME@" "" "" WriteRegStr HKLM "SOFTWARE\@APPLICATION_VENDOR@\@APPLICATION_NAME@\Capabilities" "ApplicationDescription" "@APPLICATION_DESCRIPTION@" WriteRegStr HKLM "SOFTWARE\@APPLICATION_VENDOR@\@APPLICATION_NAME@\Capabilities" "ApplicationName" "@APPLICATION_NAME@" WriteRegStr HKLM "SOFTWARE\@APPLICATION_VENDOR@\@APPLICATION_NAME@\Capabilities" "FriendlyAppName" "@APPLICATION_NAME@" WriteRegStr HKLM "SOFTWARE\RegisteredApplications" "@APPLICATION_NAME@" "SOFTWARE\@APPLICATION_VENDOR@\@APPLICATION_NAME@\Capabilities" WriteRegStr HKLM "SOFTWARE\IM Providers\@APPLICATION_NAME@" "ProcessName" "@EXECUTABLE_NAME@.exe" WriteRegStr HKLM "SOFTWARE\IM Providers\@APPLICATION_NAME@" "FriendlyName" "@APPLICATION_NAME@" # PROTOCOL declaration WriteRegStr HKCR "sip" "" "URL:sip Protocol" WriteRegStr HKCR "sip" "URL Protocol" "" WriteRegStr HKCR "sip-linphone" "" "URL:sip-linphone Protocol" WriteRegStr HKCR "sip-linphone" "URL Protocol" "" WriteRegStr HKCR "sips" "" "URL:sips Protocol" WriteRegStr HKCR "sips" "URL Protocol" "" WriteRegStr HKCR "sips-linphone" "" "URL:sips-linphone Protocol" WriteRegStr HKCR "sips-linphone" "URL Protocol" "" WriteRegStr HKCR "tel" "" "URL:tel Protocol" WriteRegStr HKCR "tel" "URL Protocol" "" WriteRegStr HKCR "callto" "" "URL:callto Protocol" WriteRegStr HKCR "callto" "URL Protocol" "" # Application protocol handlers ## SIP WriteRegStr HKCR "@APPLICATION_NAME@.sip" "" "@APPLICATION_NAME@ sip Protocol" WriteRegStr HKCR "@APPLICATION_NAME@.sip\Shell" "" "" WriteRegStr HKCR "@APPLICATION_NAME@.sip\Shell\Open" "" "" WriteRegStr HKCR "@APPLICATION_NAME@.sip\Shell\Open\Command" "" "$INSTDIR\bin\@EXECUTABLE_NAME@.exe $\"%1$\"" WriteRegStr HKLM "SOFTWARE\@APPLICATION_VENDOR@\@APPLICATION_NAME@\Capabilities\URLAssociations" "sip" "@APPLICATION_NAME@.sip" ## SIP-LINPHONE WriteRegStr HKCR "@APPLICATION_NAME@.sip-linphone" "" "@APPLICATION_NAME@ sip-linphone Protocol" WriteRegStr HKCR "@APPLICATION_NAME@.sip-linphone\Shell" "" "" WriteRegStr HKCR "@APPLICATION_NAME@.sip-linphone\Shell\Open" "" "" WriteRegStr HKCR "@APPLICATION_NAME@.sip-linphone\Shell\Open\Command" "" "$INSTDIR\bin\@EXECUTABLE_NAME@.exe $\"%1$\"" WriteRegStr HKLM "SOFTWARE\@APPLICATION_VENDOR@\@APPLICATION_NAME@\Capabilities\URLAssociations" "sip-linphone" "@APPLICATION_NAME@.sip-linphone" ## SIPS WriteRegStr HKCR "@APPLICATION_NAME@.sips" "" "@APPLICATION_NAME@ sips Protocol" WriteRegStr HKCR "@APPLICATION_NAME@.sips\Shell" "" "" WriteRegStr HKCR "@APPLICATION_NAME@.sips\Shell\Open" "" "" WriteRegStr HKCR "@APPLICATION_NAME@.sips\Shell\Open\Command" "" "$INSTDIR\bin\@EXECUTABLE_NAME@.exe $\"%1$\"" WriteRegStr HKLM "SOFTWARE\@APPLICATION_VENDOR@\@APPLICATION_NAME@\Capabilities\URLAssociations" "sips" "@APPLICATION_NAME@.sips" ## SIPS-LINPHONE WriteRegStr HKCR "@APPLICATION_NAME@.sips-linphone" "" "@APPLICATION_NAME@ sips-linphone Protocol" WriteRegStr HKCR "@APPLICATION_NAME@.sips-linphone\Shell" "" "" WriteRegStr HKCR "@APPLICATION_NAME@.sips-linphone\Shell\Open" "" "" WriteRegStr HKCR "@APPLICATION_NAME@.sips-linphone\Shell\Open\Command" "" "$INSTDIR\bin\@EXECUTABLE_NAME@.exe $\"%1$\"" WriteRegStr HKLM "SOFTWARE\@APPLICATION_VENDOR@\@APPLICATION_NAME@\Capabilities\URLAssociations" "sips-linphone" "@APPLICATION_NAME@.sips-linphone" ## TEL WriteRegStr HKCR "@APPLICATION_NAME@.tel" "" "@APPLICATION_NAME@ tel Protocol" WriteRegStr HKCR "@APPLICATION_NAME@.tel\Shell" "" "" WriteRegStr HKCR "@APPLICATION_NAME@.tel\Shell\Open" "" "" WriteRegStr HKCR "@APPLICATION_NAME@.tel\Shell\Open\Command" "" "$INSTDIR\bin\@EXECUTABLE_NAME@.exe $\"%1$\"" WriteRegStr HKLM "SOFTWARE\@APPLICATION_VENDOR@\@APPLICATION_NAME@\Capabilities\URLAssociations" "tel" "@APPLICATION_NAME@.tel" ## CALLTO WriteRegStr HKCR "@APPLICATION_NAME@.callto" "" "@APPLICATION_NAME@ callto Protocol" WriteRegStr HKCR "@APPLICATION_NAME@.callto\Shell" "" "" WriteRegStr HKCR "@APPLICATION_NAME@.callto\Shell\Open" "" "" WriteRegStr HKCR "@APPLICATION_NAME@.callto\Shell\Open\Command" "" "$INSTDIR\bin\@EXECUTABLE_NAME@.exe $\"%1$\"" WriteRegStr HKLM "SOFTWARE\@APPLICATION_VENDOR@\@APPLICATION_NAME@\Capabilities\URLAssociations" "callto" "@APPLICATION_NAME@.callto" linphone-desktop-4.2.5/linphone-app/cmake_builder/linphone_package/windows/nsis_banner.bmp000066400000000000000000021460661376717241300322010ustar00rootroot00000000000000BM66(ꆆ膆膆膆Ɔ݆̆ᆆᆆᆆᆆ§龾ͱཽʭťַͱϲ龾вᆆַ˯𾾾ᠠ묬цᆆҖﯯ‰چ쮮說نᆆڋꑑȈцᆆӋՆꖖʉꑑن㒒ᆆЊꉉцᆆȆdž獍نމᆆڈɆ̆цᆆֆ󊊊Іنꊊᆆ銊݆ن᫫םʗцᆆ̆尰뻻†༼Ԗ񋋋̘ӻםنǎᆆ֥‹ʆІ‡цᆆȆ㏏ꆆć醆҆Ѝنdž򛛛ᆆӆَƆ莎Ά􇇇ֈцᆆۆꆆ߆񆆆ڈĆꏏنᆆ퓓نᆆ̆цᆆÆ܆񊊊ІɆↆↆنцdžᆆ톆ↆ솆Ćцᆆ̆ↆdž円膆򆆆نᆆ̆ƈ솆цᆆ醆ʆ͆䆆톆نᆆنՆцᆆІІֆن膆Ćᆆ膆醆цᆆ†솆󆆆Ć膆نԆچᆆцᆆܕІↆ׆݆نƆ醆ᆆنцᆆ槧؆߆񆆆نᆆ膆†نцᆆަنކنᆆ膆†نцᆆӜᆆن҆نᆆ膆†نцᆆДᆆنʆنᆆ膆†نцᆆ쟟ᆆن̆ņنᆆ膆نцᆆކކ醆†نᆆ膆݆цᆆꋋ؆ᆆƆنᆆ膆䆆цᆆІ膆†نĆ膆ᆆن솆솆цᆆ󆆆򆆆ۆ†솆نφ׆ᆆ҆چц݆Ɇ͆†چنↆ†ᆆdž߆Æ䆆Æц؆††Æنᆆ҆ᆆцɆچۆ߆Ɇ†ߊنᆆچۆІц߆Ն׆ꆆ†цنĆᆆ񆆆ԆцچنԆ†ن鈈ᆆ܆񉉉͆̆ццц匌؆ĆԆdž̆̆ن򖖖ᆆᆆ싋ʈц陙݆͊̈؆ʆ솆نےᆆߒ쇇䚚ццÆ㇇ՆԆنφᆆ튊𓓓цȆކنᆆՆڇцΆĆ醆ĆڇنۏᆆЇޏ̍цɍޗώĆ熆ކޏن厎ڔᆆ㘘ŋ컻ś૫촴Ɯ˫ЫƫښժǜÆ嫫񯯯УꫫѥƟ򆆆ↆ͆ӆ䆆솆Ȇ߆ֆ鏏ņㆆΆό뭭켼ּІ򙙙򆆆醆ڜ݆ǎFGG:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<FGG:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<FGG:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<FGG:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<FGG:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<FGG:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<FGG:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<FGG:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<FGG:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<FGG:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<FGG:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<FGG:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<FGG:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<FGG:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<FGG:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<FGG:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<FGG:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<FGG:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<FGG:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<FGG:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<FGG:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<FGG:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<FGG:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<FGG:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<FGG:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<FGG:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<FGG:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<FGG:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<FGG:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<FGG:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<FGG:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<FGG:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<FGG:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<FGG:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<FGG:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<FGG:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<FGG:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<FGG:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<٤yzzRTT;==:<<:<<:<<:<<:<<:<<:<<:<<:<<;==MNNdff۱qrrTVV?AA:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<>:<<:<<=??FGGLNN^__oqqFGG:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<IKK:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<>oqq:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<ꞟRTT:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<\^^\^^:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<>Z[[:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<@@acc:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<>:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<>:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<;==:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<^``:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<>:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<^``:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<@@:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<>EGG:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<@@Z\\xyyȳmnnNPP:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<<>>:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<>:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<@BB:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<^``:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<>wxxꡢQSS:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<@@:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<>:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<>:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<@@EGG:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<>BDD:<>:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<>:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<^``:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<>:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<@@:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<>qrr:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<>:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<;==xyy:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<^``:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<@@:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<@BB:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<^``:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<>:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<>:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<@@:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<>:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<^``:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<>:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<>Z[[:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<@@:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<_aa;==:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<><>>:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<>:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<=??:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<>:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<^``:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<@@:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<>Wfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<@@[]]:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<@@:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<@@:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<^``:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<@BB磌]^^:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<>yzzhii:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<>:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<>:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<[]]˻z{{IKK:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<[]] ifffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffk:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<>:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<\^^:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<^``:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<@@:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<>:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<@@:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<>.}fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff-}:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<@@<>>:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<>:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<><>>:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<>FGG:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<@@:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<@@:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<>FGG:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<>PQQ:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<@@{||:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<<>>:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<@@:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<>:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<>:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<|}}:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<@@xyy:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<<>>:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<^``:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<>:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<>:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<~fffffffffffffff gjBfffffffffffffffffffffffffffffffffffffffffffffffffffffL:<<:<<:<<:<<:<<:<<:<<:<<:<@@:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<^``:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<>:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<>:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<@@fffffffffffffBBfffffffffffffffffffffffffffffffffffffffffffffL:<<:<<:<<:<<:<<:<<:<<<>>홚JLL:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<>hjj:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<>:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<@BB{||^``:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<;==rtt:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<^``㵶:<<:<<:<<:<<:<<:<<鬬rssACC:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<@@:<<:<<:<<:<<Ө_aaACC:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<>:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<>:<>]^^:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<^``ɡaccMNN<>>:<<:<<:<<:<<:<<:<<<>>IKK[]]rss:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<>:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<^``:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<^``CEE:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<>:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<^``MOO:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<@@VXX:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:<<:< assets/fonts/NotoSans-hinted/NotoSans-BoldItalic.ttf assets/fonts/NotoSans-hinted/NotoSans-Bold.ttf assets/fonts/NotoSans-hinted/NotoSans-Italic.ttf assets/fonts/NotoSans-hinted/NotoSans-Regular.ttf assets/fonts/NotoSans-hinted/NotoSansUI-BoldItalic.ttf assets/fonts/NotoSans-hinted/NotoSansUI-Bold.ttf assets/fonts/NotoSans-hinted/NotoSansUI-Italic.ttf assets/fonts/NotoSans-hinted/NotoSansUI-Regular.ttf assets/images/add_disabled.svg assets/images/add_hovered.svg assets/images/add_normal.svg assets/images/add_pressed.svg assets/images/attachment_disabled.svg assets/images/attachment_hovered.svg assets/images/attachment_normal.svg assets/images/attachment_pressed.svg assets/images/auto_answer.svg assets/images/burger_menu_hovered.svg assets/images/burger_menu_light_hovered.svg assets/images/burger_menu_light_normal.svg assets/images/burger_menu_light_pressed.svg assets/images/burger_menu_normal.svg assets/images/burger_menu_pressed.svg assets/images/call_accept_hovered.svg assets/images/call_accept_normal.svg assets/images/call_accept_pressed.svg assets/images/call_chat_secure_hovered.svg assets/images/call_chat_secure_normal.svg assets/images/call_chat_secure_pressed.svg assets/images/call_chat_unsecure_hovered.svg assets/images/call_chat_unsecure_normal.svg assets/images/call_chat_unsecure_pressed.svg assets/images/call_hovered.svg assets/images/call_normal.svg assets/images/call_pressed.svg assets/images/call_quality_0.svg assets/images/call_quality_1.svg assets/images/call_quality_2.svg assets/images/call_quality_3.svg assets/images/call_sign_connected.svg assets/images/call_sign_ended.svg assets/images/call_sign_incoming.svg assets/images/call_sign_outgoing.svg assets/images/call_sign_paused.svg assets/images/camera_off_hovered.svg assets/images/camera_off_normal.svg assets/images/camera_off_pressed.svg assets/images/camera_off_updating.svg assets/images/camera_on_hovered.svg assets/images/camera_on_normal.svg assets/images/camera_on_pressed.svg assets/images/camera_on_updating.svg assets/images/camera.svg assets/images/cancel_hovered.svg assets/images/cancel_normal.svg assets/images/cancel_pressed.svg assets/images/chat_amount.svg assets/images/chat_count.svg assets/images/chat_delivered.svg assets/images/chat_error.svg assets/images/chat_hovered.svg assets/images/chat_is_composing_0.svg assets/images/chat_is_composing_1.svg assets/images/chat_is_composing_2.svg assets/images/chat_is_composing_3.svg assets/images/chat_normal.svg assets/images/chat_pressed.svg assets/images/chat_read.svg assets/images/collapse.svg assets/images/contact_add_hovered.svg assets/images/contact_add_normal.svg assets/images/contact_add_pressed.svg assets/images/contact_add.svg assets/images/contact_card_photo_disabled.svg assets/images/contact_card_photo_hovered.svg assets/images/contact_card_photo_normal.svg assets/images/contact_card_photo_pressed.svg assets/images/contact_edit_hovered.svg assets/images/contact_edit_normal.svg assets/images/contact_edit_pressed.svg assets/images/contact_normal.svg assets/images/contact_selected.svg assets/images/declined_incoming_call.svg assets/images/declined_outgoing_call.svg assets/images/delete_hovered.svg assets/images/delete_normal.svg assets/images/delete_pressed.svg assets/images/download.svg assets/images/drop_down.svg assets/images/edit_hovered.svg assets/images/edit_normal.svg assets/images/edit_pressed.svg assets/images/ended_call.svg assets/images/file_hovered.svg assets/images/file_normal.svg assets/images/file_pressed.svg assets/images/file_sign.svg assets/images/filter.svg assets/images/folder_hovered.svg assets/images/folder_normal.svg assets/images/folder_pressed.svg assets/images/fullscreen_hovered.svg assets/images/fullscreen_normal.svg assets/images/fullscreen_pressed.svg assets/images/generic_error_hovered.svg assets/images/generic_error_normal.svg assets/images/generic_error_pressed.svg assets/images/generic_error.svg assets/images/hangup_hovered.svg assets/images/hangup_normal.svg assets/images/hangup_pressed.svg assets/images/history_hovered.svg assets/images/history_normal.svg assets/images/history_pressed.svg assets/images/history.svg assets/images/home_account_assistant.svg assets/images/home_invite_friends.svg assets/images/home_normal.svg assets/images/home_selected.svg assets/images/home_use_linphone.svg assets/images/incoming_call.svg assets/images/led_green.svg assets/images/led_orange.svg assets/images/led_red.svg assets/images/led_white.svg assets/images/message_sign.svg assets/images/micro_off_hovered.svg assets/images/micro_off_normal.svg assets/images/micro_off_pressed.svg assets/images/micro_on_hovered.svg assets/images/micro_on_normal.svg assets/images/micro_on_pressed.svg assets/images/micro.svg assets/images/missed_incoming_call.svg assets/images/missed_outgoing_call.svg assets/images/new_call_hovered.svg assets/images/new_call_normal.svg assets/images/new_call_pressed.svg assets/images/new_conference_hovered.svg assets/images/new_conference_normal.svg assets/images/new_conference_pressed.svg assets/images/options_hovered.svg assets/images/options_normal.svg assets/images/options_pressed.svg assets/images/outgoing_call.svg assets/images/pause_off_hovered.svg assets/images/pause_off_normal.svg assets/images/pause_off_pressed.svg assets/images/pause_off_updating.svg assets/images/pause_on_hovered.svg assets/images/pause_on_normal.svg assets/images/pause_on_pressed.svg assets/images/pause_on_updating.svg assets/images/recording_sign.svg assets/images/record_off.svg assets/images/record_on.svg assets/images/screenshot_hovered.svg assets/images/screenshot_normal.svg assets/images/screenshot_pressed.svg assets/images/search.svg assets/images/settings_advanced_normal.svg assets/images/settings_advanced_selected.svg assets/images/settings_audio_normal.svg assets/images/settings_audio_selected.svg assets/images/settings_call_normal.svg assets/images/settings_call_selected.svg assets/images/settings_network_normal.svg assets/images/settings_network_selected.svg assets/images/settings_sip_accounts_normal.svg assets/images/settings_sip_accounts_selected.svg assets/images/settings_video_normal.svg assets/images/settings_video_selected.svg assets/images/snapshot_sign.svg assets/images/speaker_off_hovered.svg assets/images/speaker_off_normal.svg assets/images/speaker_off_pressed.svg assets/images/speaker_on_hovered.svg assets/images/speaker_on_normal.svg assets/images/speaker_on_pressed.svg assets/images/speaker.svg assets/images/tel_keypad_hovered.svg assets/images/tel_keypad_normal.svg assets/images/tel_keypad_pressed.svg assets/images/timeline_history.svg assets/images/tooltip_arrow_bottom.svg assets/images/tooltip_arrow_left.svg assets/images/tooltip_arrow_right.svg assets/images/tooltip_arrow_top.svg assets/images/transfer_hovered.svg assets/images/transfer_normal.svg assets/images/transfer_pressed.svg assets/images/update_sign.svg assets/images/video_call_accept_hovered.svg assets/images/video_call_accept_normal.svg assets/images/video_call_accept_pressed.svg assets/images/video_call_hovered.svg assets/images/video_call_normal.svg assets/images/video_call_pressed.svg assets/images/warning.svg ui/modules/Common/Animations/BusyIndicator.qml ui/modules/Common/Constants/Constants.qml ui/modules/Common/Dialog/ConfirmDialog.qml ui/modules/Common/Dialog/DialogDescription.qml ui/modules/Common/Dialog/DialogPlus.qml ui/modules/Common/Form/ActionBar.qml ui/modules/Common/Form/ActionButton.qml ui/modules/Common/Form/ActionSwitch.qml ui/modules/Common/Form/Buttons/AbstractTextButton.qml ui/modules/Common/Form/Buttons/ExclusiveButtons.qml ui/modules/Common/Form/Buttons/FileChooserButton.qml ui/modules/Common/Form/Buttons/SmallButton.qml ui/modules/Common/Form/Buttons/TextButtonA.qml ui/modules/Common/Form/Buttons/TextButtonB.qml ui/modules/Common/Form/CheckBoxText.qml ui/modules/Common/Form/ComboBox.js ui/modules/Common/Form/ComboBox.qml ui/modules/Common/Form/CommonItemDelegate.qml ui/modules/Common/Form/DroppableTextArea.qml ui/modules/Common/Form/Fields/HexField.qml ui/modules/Common/Form/Fields/NumericField.qml ui/modules/Common/Form/Fields/PasswordField.qml ui/modules/Common/Form/Fields/PortField.qml ui/modules/Common/Form/Fields/ScrollableListViewField.qml ui/modules/Common/Form/Fields/TextAreaField.qml ui/modules/Common/Form/Fields/TextField.qml ui/modules/Common/Form/ListForm.js ui/modules/Common/Form/ListForm.qml ui/modules/Common/Form/ListItemSelector.js ui/modules/Common/Form/ListItemSelector.qml ui/modules/Common/Form/MouseArea.qml ui/modules/Common/Form/Placements/FormEmptyLine.qml ui/modules/Common/Form/Placements/FormGroup.qml ui/modules/Common/Form/Placements/FormHGroup.qml ui/modules/Common/Form/Placements/FormLine.qml ui/modules/Common/Form/Placements/Form.qml ui/modules/Common/Form/Placements/FormTableEntry.qml ui/modules/Common/Form/Placements/FormTableLine.qml ui/modules/Common/Form/Placements/FormTable.qml ui/modules/Common/Form/Placements/FormVGroup.qml ui/modules/Common/Form/SearchBox.qml ui/modules/Common/Form/Slider.qml ui/modules/Common/Form/StaticListForm.qml ui/modules/Common/Form/Switch.qml ui/modules/Common/Form/Tab/TabBar.qml ui/modules/Common/Form/Tab/TabButton.qml ui/modules/Common/Form/Tab/TabContainer.qml ui/modules/Common/Form/TransparentTextInput.qml ui/modules/Common/Helpers/DragBox.qml ui/modules/Common/Helpers/InvertedMouseArea.qml ui/modules/Common/Image/Icon.qml ui/modules/Common/Image/RoundedImage.qml ui/modules/Common/Indicators/VuMeter.qml ui/modules/Common/Menus/ApplicationMenuEntry.qml ui/modules/Common/Menus/ApplicationMenu.qml ui/modules/Common/Menus/DropDownDynamicMenu.qml ui/modules/Common/Menus/DropDownStaticMenuEntry.qml ui/modules/Common/Menus/DropDownStaticMenu.qml ui/modules/Common/Menus/MenuItem.qml ui/modules/Common/Menus/Menu.qml ui/modules/Common/Misc/Borders.qml ui/modules/Common/Misc/ForceScrollBar.qml ui/modules/Common/Misc/Paned.qml ui/modules/Common/Popup/DesktopPopup.qml ui/modules/Common/Popup/Popup.qml ui/modules/Common/Popup/PopupShadow.qml ui/modules/Common/qmldir ui/modules/Common/Styles/Animations/BusyIndicatorStyle.qml ui/modules/Common/Styles/Dialog/DialogStyle.qml ui/modules/Common/Styles/Form/ActionBarStyle.qml ui/modules/Common/Styles/Form/Buttons/AbstractTextButtonStyle.qml ui/modules/Common/Styles/Form/Buttons/ExclusiveButtonsStyle.qml ui/modules/Common/Styles/Form/Buttons/FileChooserButtonStyle.qml ui/modules/Common/Styles/Form/Buttons/SmallButtonStyle.qml ui/modules/Common/Styles/Form/Buttons/TextButtonAStyle.qml ui/modules/Common/Styles/Form/Buttons/TextButtonBStyle.qml ui/modules/Common/Styles/Form/CheckBoxTextStyle.qml ui/modules/Common/Styles/Form/ComboBoxStyle.qml ui/modules/Common/Styles/Form/CommonItemDelegateStyle.qml ui/modules/Common/Styles/Form/DroppableTextAreaStyle.qml ui/modules/Common/Styles/Form/Fields/NumericFieldStyle.qml ui/modules/Common/Styles/Form/Fields/TextAreaFieldStyle.qml ui/modules/Common/Styles/Form/Fields/TextFieldStyle.qml ui/modules/Common/Styles/Form/ListFormStyle.qml ui/modules/Common/Styles/Form/Placements/FormHGroupStyle.qml ui/modules/Common/Styles/Form/Placements/FormLineStyle.qml ui/modules/Common/Styles/Form/Placements/FormStyle.qml ui/modules/Common/Styles/Form/Placements/FormTableLineStyle.qml ui/modules/Common/Styles/Form/Placements/FormTableStyle.qml ui/modules/Common/Styles/Form/Placements/FormVGroupStyle.qml ui/modules/Common/Styles/Form/SearchBoxStyle.qml ui/modules/Common/Styles/Form/SliderStyle.qml ui/modules/Common/Styles/Form/SwitchStyle.qml ui/modules/Common/Styles/Form/Tab/TabButtonStyle.qml ui/modules/Common/Styles/Form/Tab/TabContainerStyle.qml ui/modules/Common/Styles/Form/TransparentTextInputStyle.qml ui/modules/Common/Styles/Indicators/VuMeterStyle.qml ui/modules/Common/Styles/Menus/ApplicationMenuStyle.qml ui/modules/Common/Styles/Menus/DropDownStaticMenuStyle.qml ui/modules/Common/Styles/Menus/MenuItemStyle.qml ui/modules/Common/Styles/Menus/MenuStyle.qml ui/modules/Common/Styles/Misc/ForceScrollBarStyle.qml ui/modules/Common/Styles/Misc/PanedStyle.qml ui/modules/Common/Styles/Popup/PopupStyle.qml ui/modules/Common/Styles/qmldir ui/modules/Common/Styles/Tooltip/TooltipStyle.qml ui/modules/Common/Styles/Window/WindowStyle.qml ui/modules/Common/Tooltip/TooltipArea.qml ui/modules/Common/Tooltip/Tooltip.qml ui/modules/Common/View/ScrollableListView.qml ui/modules/Common/Window/ApplicationWindow.qml ui/modules/Common/Window/VirtualWindow.qml ui/modules/Common/Window/Window.js ui/modules/Common/Window/Window.qml ui/modules/Konami/Konami.qml ui/modules/Konami/qmldir ui/modules/Linphone/Account/AccountStatus.qml ui/modules/Linphone/Blocks/CardBlock.qml ui/modules/Linphone/Blocks/RequestBlock.qml ui/modules/Linphone/Calls/CallControls.qml ui/modules/Linphone/Calls/Calls.js ui/modules/Linphone/Calls/Calls.qml ui/modules/Linphone/Calls/CallStatistics.qml ui/modules/Linphone/Calls/ConferenceControls.qml ui/modules/Linphone/Chat/Chat.js ui/modules/Linphone/Chat/Chat.qml ui/modules/Linphone/Chat/Event.qml ui/modules/Linphone/Chat/FileMessage.qml ui/modules/Linphone/Chat/IncomingMessage.qml ui/modules/Linphone/Chat/Message.js ui/modules/Linphone/Chat/Message.qml ui/modules/Linphone/Chat/OutgoingMessage.qml ui/modules/Linphone/Codecs/CodecAttribute.qml ui/modules/Linphone/Codecs/CodecLegend.qml ui/modules/Linphone/Codecs/CodecsViewer.qml ui/modules/Linphone/Contact/Avatar.qml ui/modules/Linphone/Contact/ContactDescription.qml ui/modules/Linphone/Contact/ContactMessageCounter.qml ui/modules/Linphone/Contact/Contact.qml ui/modules/Linphone/Dialog/OnlineInstallerDialog.qml ui/modules/Linphone/History/History.qml ui/modules/Linphone/History/History.js ui/modules/Linphone/History/Event.qml ui/modules/Linphone/Menus/SipAddressesMenu.qml ui/modules/Linphone/Misc/MessageCounter.qml ui/modules/Linphone/Notifications/NotificationBasic.qml ui/modules/Linphone/Notifications/NotificationNewVersionAvailable.qml ui/modules/Linphone/Notifications/Notification.qml ui/modules/Linphone/Notifications/NotificationReceivedCall.qml ui/modules/Linphone/Notifications/NotificationReceivedFileMessage.qml ui/modules/Linphone/Notifications/NotificationReceivedMessage.qml ui/modules/Linphone/Notifications/NotificationRecordingCompleted.qml ui/modules/Linphone/Notifications/NotificationSnapshotWasTaken.qml ui/modules/Linphone/Presence/PresenceLevel.qml ui/modules/Linphone/qmldir ui/modules/Linphone/SmartSearchBar/SmartSearchBar.qml ui/modules/Linphone/Styles/Account/AccountStatusStyle.qml ui/modules/Linphone/Styles/Blocks/CardBlockStyle.qml ui/modules/Linphone/Styles/Blocks/RequestBlockStyle.qml ui/modules/Linphone/Styles/Calls/CallControlsStyle.qml ui/modules/Linphone/Styles/Calls/CallsStyle.qml ui/modules/Linphone/Styles/Calls/CallStatisticsStyle.qml ui/modules/Linphone/Styles/Calls/ConferenceControlsStyle.qml ui/modules/Linphone/Styles/Chat/ChatStyle.qml ui/modules/Linphone/Styles/Codecs/CodecsViewerStyle.qml ui/modules/Linphone/Styles/Contact/AvatarStyle.qml ui/modules/Linphone/Styles/Contact/ContactDescriptionStyle.qml ui/modules/Linphone/Styles/Contact/ContactMessageCounterStyle.qml ui/modules/Linphone/Styles/Contact/ContactStyle.qml ui/modules/Linphone/Styles/Dialog/OnlineInstallerDialogStyle.qml ui/modules/Linphone/Styles/History/HistoryStyle.qml ui/modules/Linphone/Styles/Menus/SipAddressesMenuStyle.qml ui/modules/Linphone/Styles/Misc/MessageCounterStyle.qml ui/modules/Linphone/Styles/Notifications/NotificationBasicStyle.qml ui/modules/Linphone/Styles/Notifications/NotificationReceivedCallStyle.qml ui/modules/Linphone/Styles/Notifications/NotificationReceivedFileMessageStyle.qml ui/modules/Linphone/Styles/Notifications/NotificationReceivedMessageStyle.qml ui/modules/Linphone/Styles/Notifications/NotificationStyle.qml ui/modules/Linphone/Styles/qmldir ui/modules/Linphone/Styles/TelKeypad/TelKeypadStyle.qml ui/modules/Linphone/Styles/Timeline/TimelineStyle.qml ui/modules/Linphone/Styles/View/SipAddressesViewStyle.qml ui/modules/Linphone/TelKeypad/TelKeypadButton.qml ui/modules/Linphone/TelKeypad/TelKeypad.js ui/modules/Linphone/TelKeypad/TelKeypad.qml ui/modules/Linphone/Timeline/Timeline.js ui/modules/Linphone/Timeline/Timeline.qml ui/modules/Linphone/View/SipAddressesView.qml ui/scripts/LinphoneUtils/linphone-utils.js ui/scripts/LinphoneUtils/qmldir ui/scripts/Utils/port-tools.js ui/scripts/Utils/qmldir ui/scripts/Utils/uri-tools.js ui/scripts/Utils/utils.js ui/views/App/Calls/AbstractStartingCall.qml ui/views/App/Calls/CallsWindow.js ui/views/App/Calls/CallsWindow.qml ui/views/App/Calls/Conference.qml ui/views/App/Calls/Dialogs/CallSipAddress.qml ui/views/App/Calls/Dialogs/CallTransfer.qml ui/views/App/Calls/Dialogs/ConferenceManager.qml ui/views/App/Calls/Dialogs/MultimediaParameters.qml ui/views/App/Calls/EndedCall.qml ui/views/App/Calls/IncallAvatar.qml ui/views/App/Calls/IncallFullscreenWindow.qml ui/views/App/Calls/Incall.js ui/views/App/Calls/Incall.qml ui/views/App/Calls/IncomingCall.qml ui/views/App/Calls/OutgoingCall.qml ui/views/App/Calls/ZrtpTokenAuthentication.qml ui/views/App/Main/Assistant/ActivateAppSipAccountWithEmail.qml ui/views/App/Main/Assistant/ActivateAppSipAccountWithPhoneNumber.qml ui/views/App/Main/Assistant/AssistantAbstractView.qml ui/views/App/Main/Assistant/AssistantHome.qml ui/views/App/Main/Assistant/CreateAppSipAccount.qml ui/views/App/Main/Assistant/CreateAppSipAccountWithEmail.qml ui/views/App/Main/Assistant/CreateAppSipAccountWithPhoneNumber.qml ui/views/App/Main/Assistant/FetchRemoteConfiguration.qml ui/views/App/Main/Assistant.qml ui/views/App/Main/Assistant/UseAppSipAccount.qml ui/views/App/Main/Assistant/UseAppSipAccountWithPhoneNumber.qml ui/views/App/Main/Assistant/UseAppSipAccountWithUsername.qml ui/views/App/Main/Assistant/UseOtherSipAccount.qml ui/views/App/Main/ContactEdit.js ui/views/App/Main/ContactEdit.qml ui/views/App/Main/Contacts.qml ui/views/App/Main/Conversation.js ui/views/App/Main/Conversation.qml ui/views/App/Main/Dialogs/About.qml ui/views/App/Main/Dialogs/AuthenticationRequest.js ui/views/App/Main/Dialogs/AuthenticationRequest.qml ui/views/App/Main/Dialogs/ManageAccount.js ui/views/App/Main/Dialogs/ManageAccounts.qml ui/views/App/Main/Home.qml ui/views/App/Main/HistoryView.qml ui/views/App/Main/HistoryView.js ui/views/App/Main/InviteFriends.qml ui/views/App/Main/MainWindow.js ui/views/App/Main/MainWindowMenuBar.qml ui/views/App/Main/MainWindow.qml ui/views/App/Main/MainWindowTopMenuBar.qml ui/views/App/Settings/Dialogs/SettingsSipAccountsEdit.js ui/views/App/Settings/Dialogs/SettingsSipAccountsEdit.qml ui/views/App/Settings/Dialogs/SettingsVideoPreview.qml ui/views/App/Settings/SettingsAdvanced.js ui/views/App/Settings/SettingsAdvanced.qml ui/views/App/Settings/SettingsAudio.qml ui/views/App/Settings/SettingsCallsChat.qml ui/views/App/Settings/SettingsNetwork.qml ui/views/App/Settings/SettingsSipAccounts.js ui/views/App/Settings/SettingsSipAccounts.qml ui/views/App/Settings/SettingsUi.js ui/views/App/Settings/SettingsUi.qml ui/views/App/Settings/SettingsVideo.js ui/views/App/Settings/SettingsVideo.qml ui/views/App/Settings/SettingsWindow.qml ui/views/App/Styles/Calls/CallStyle.qml ui/views/App/Styles/Calls/CallsWindowStyle.qml ui/views/App/Styles/Calls/ConferenceStyle.qml ui/views/App/Styles/Calls/Dialogs/CallSipAddressStyle.qml ui/views/App/Styles/Calls/Dialogs/CallTransferStyle.qml ui/views/App/Styles/Calls/Dialogs/ConferenceManagerStyle.qml ui/views/App/Styles/Calls/Dialogs/MultimediaParametersStyle.qml ui/views/App/Styles/Main/Assistant/ActivateAppSipAccountWithEmailStyle.qml ui/views/App/Styles/Main/Assistant/ActivateAppSipAccountWithPhoneNumberStyle.qml ui/views/App/Styles/Main/Assistant/AssistantAbstractViewStyle.qml ui/views/App/Styles/Main/Assistant/AssistantHomeStyle.qml ui/views/App/Styles/Main/Assistant/CreateAppSipAccountStyle.qml ui/views/App/Styles/Main/AssistantStyle.qml ui/views/App/Styles/Main/Assistant/UseAppSipAccountStyle.qml ui/views/App/Styles/Main/ContactEditStyle.qml ui/views/App/Styles/Main/ContactsStyle.qml ui/views/App/Styles/Main/ConversationStyle.qml ui/views/App/Styles/Main/Dialogs/AboutStyle.qml ui/views/App/Styles/Main/Dialogs/AuthenticationRequestStyle.qml ui/views/App/Styles/Main/Dialogs/ManageAccountsStyle.qml ui/views/App/Styles/Main/HomeStyle.qml ui/views/App/Styles/Main/InviteFriendsStyle.qml ui/views/App/Styles/Main/HistoryViewStyle.qml ui/views/App/Styles/Main/MainWindowStyle.qml ui/views/App/Styles/qmldir ui/views/App/Styles/Settings/Dialogs/SettingsSipAccountsEditStyle.qml ui/views/App/Styles/Settings/Dialogs/SettingsVideoPreviewStyle.qml ui/views/App/Styles/Settings/SettingsAdvancedStyle.qml ui/views/App/Styles/Settings/SettingsAudioStyle.qml ui/views/App/Styles/Settings/SettingsWindowStyle.qml assets/images/linphone_logo.svg ui/dev-modules/Colors/Colors.qml ui/dev-modules/Units/Units.qml assets/icon.ico linphone-desktop-4.2.5/linphone-app/src/000077500000000000000000000000001376717241300202015ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/src/app/000077500000000000000000000000001376717241300207615ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/src/app/App.cpp000066400000000000000000000665331376717241300222220ustar00rootroot00000000000000/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "App.hpp" #ifdef Q_OS_WIN #include #endif // ifdef Q_OS_WIN #include #include #include #include #include #include #include #include #include #include #include #include "config.h" #include "cli/Cli.hpp" #include "components/Components.hpp" #include "logger/Logger.hpp" #include "paths/Paths.hpp" #include "providers/AvatarProvider.hpp" #include "providers/ImageProvider.hpp" #include "providers/ExternalImageProvider.hpp" #include "providers/ThumbnailProvider.hpp" #include "translator/DefaultTranslator.hpp" #include "utils/LinphoneUtils.hpp" #include "utils/Utils.hpp" #include "components/other/desktop-tools/DesktopTools.hpp" // ============================================================================= using namespace std; namespace { constexpr char DefaultLocale[] = "en"; constexpr char LanguagePath[] = ":/languages/"; // The main windows of Linphone desktop. constexpr char QmlViewMainWindow[] = "qrc:/ui/views/App/Main/MainWindow.qml"; constexpr char QmlViewCallsWindow[] = "qrc:/ui/views/App/Calls/CallsWindow.qml"; constexpr char QmlViewSettingsWindow[] = "qrc:/ui/views/App/Settings/SettingsWindow.qml"; #ifdef ENABLE_UPDATE_CHECK constexpr int VersionUpdateCheckInterval = 86400000; // 24 hours in milliseconds. #endif // ifdef ENABLE_UPDATE_CHECK constexpr char MainQmlUri[] = "Linphone"; constexpr char AttachVirtualWindowMethodName[] = "attachVirtualWindow"; constexpr char AboutPath[] = "qrc:/ui/views/App/Main/Dialogs/About.qml"; constexpr char AssistantViewName[] = "Assistant"; #ifdef Q_OS_LINUX const QString AutoStartDirectory(QDir::homePath().append(QStringLiteral("/.config/autostart/"))); #elif defined(Q_OS_MACOS) const QString OsascriptExecutable(QStringLiteral("osascript")); #else const QString AutoStartSettingsFilePath( QStringLiteral("HKEY_CURRENT_USER\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run") ); #endif // ifdef Q_OS_LINUX } // ----------------------------------------------------------------------------- #ifdef Q_OS_LINUX static inline bool autoStartEnabled () { return QDir(AutoStartDirectory).exists() && QFile(AutoStartDirectory + EXECUTABLE_NAME ".desktop").exists(); } #elif defined(Q_OS_MACOS) static inline QString getMacOsBundlePath () { QDir dir(QCoreApplication::applicationDirPath()); if (dir.dirName() != QLatin1String("MacOS")) return QString(); dir.cdUp(); dir.cdUp(); QString path(dir.path()); if (path.length() > 0 && path.right(1) == "/") path.chop(1); return path; } static inline QString getMacOsBundleName () { return QFileInfo(getMacOsBundlePath()).baseName(); } static inline bool autoStartEnabled () { const QByteArray expectedWord(getMacOsBundleName().toUtf8()); if (expectedWord.isEmpty()) { qInfo() << QStringLiteral("Application is not installed. Autostart unavailable."); return false; } QProcess process; process.start(OsascriptExecutable, { "-e", "tell application \"System Events\" to get the name of every login item" }); if (!process.waitForFinished()) { qWarning() << QStringLiteral("Unable to execute properly: `%1` (%2).").arg(OsascriptExecutable).arg(process.errorString()); return false; } // TODO: Move in utils? const QByteArray buf(process.readAll()); for (const char *p = buf.data(), *word = p, *end = p + buf.length(); p <= end; ++p) { switch (*p) { case ' ': case '\r': case '\n': case '\t': case '\0': if (word != p) { if (!strncmp(word, expectedWord, size_t(p - word))) return true; word = p + 1; } default: break; } } return false; } #else static inline bool autoStartEnabled () { return QSettings(AutoStartSettingsFilePath, QSettings::NativeFormat).value(EXECUTABLE_NAME).isValid(); } #endif // ifdef Q_OS_LINUX // ----------------------------------------------------------------------------- static inline bool installLocale (App &app, QTranslator &translator, const QLocale &locale) { return translator.load(locale, LanguagePath) && app.installTranslator(&translator); } static inline shared_ptr getConfigIfExists (const QCommandLineParser &parser) { string configPath(Paths::getConfigFilePath(parser.value("config"), false)); if (!Paths::filePathExists(configPath)) configPath.clear(); string factoryPath(Paths::getFactoryConfigFilePath()); if (!Paths::filePathExists(factoryPath)) factoryPath.clear(); return linphone::Config::newWithFactory(configPath, factoryPath); } // ----------------------------------------------------------------------------- App::App (int &argc, char *argv[]) : SingleApplication(argc, argv, true, Mode::User | Mode::ExcludeAppPath | Mode::ExcludeAppVersion) { connect(this, SIGNAL(applicationStateChanged(Qt::ApplicationState)), this, SLOT(stateChanged(Qt::ApplicationState))); setWindowIcon(QIcon(LinphoneUtils::WindowIconPath)); createParser(); mParser->process(*this); // Initialize logger. shared_ptr config = getConfigIfExists(*mParser); Logger::init(config); if (mParser->isSet("verbose")) Logger::getInstance()->setVerbose(true); // List available locales. for (const auto &locale : QDir(LanguagePath).entryList()) mAvailableLocales << QLocale(locale); // Init locale. mTranslator = new DefaultTranslator(this); mDefaultTranslator = new DefaultTranslator(this); initLocale(config); if (mParser->isSet("help")) { createParser(); mParser->showHelp(); } if (mParser->isSet("cli-help")) { Cli::showHelp(); ::exit(EXIT_SUCCESS); } if (mParser->isSet("version")) mParser->showVersion(); mAutoStart = autoStartEnabled(); qInfo() << QStringLiteral("Starting " APPLICATION_NAME " (bin: " EXECUTABLE_NAME ")"); qInfo() << QStringLiteral("Use locale: %1").arg(mLocale); } App::~App () { qInfo() << QStringLiteral("Destroying app..."); delete mEngine; delete mParser; } // ----------------------------------------------------------------------------- static QQuickWindow *createSubWindow (QQmlApplicationEngine *engine, const char *path) { qInfo() << QStringLiteral("Creating subwindow: `%1`.").arg(path); QQmlComponent component(engine, QUrl(path)); if (component.isError()) { qWarning() << component.errors(); abort(); } qInfo() << QStringLiteral("Subwindow status: `%1`.").arg(component.status()); QObject *object = component.create(); Q_ASSERT(object); QQmlEngine::setObjectOwnership(object, QQmlEngine::CppOwnership); object->setParent(engine); return qobject_cast(object); } // ----------------------------------------------------------------------------- void App::initContentApp () { shared_ptr config = getConfigIfExists(*mParser); bool mustBeIconified = false; // Destroy qml components and linphone core if necessary. if (mEngine) { setOpened(false); qInfo() << QStringLiteral("Restarting app..."); delete mEngine; mNotifier = nullptr; mSystemTrayIcon = nullptr; CoreManager::uninit(); removeTranslator(mTranslator); removeTranslator(mDefaultTranslator); delete mTranslator; delete mDefaultTranslator; mTranslator = new DefaultTranslator(this); mDefaultTranslator = new DefaultTranslator(this); initLocale(config); } else { // Update and download codecs. VideoCodecsModel::updateCodecs(); VideoCodecsModel::downloadUpdatableCodecs(this); // Don't quit if last window is closed!!! setQuitOnLastWindowClosed(false); // Deal with received messages and CLI. QObject::connect(this, &App::receivedMessage, this, [](int, const QByteArray &byteArray) { QString command(byteArray); qInfo() << QStringLiteral("Received command from other application: `%1`.").arg(command); Cli::executeCommand(command); }); #ifndef Q_OS_MACOS mustBeIconified = mParser->isSet("iconified"); #endif // ifndef Q_OS_MACOS mColors = new Colors(this); } // Change colors if necessary. mColors->useConfig(config); // Init core. CoreManager::init(this, mParser->value("config")); // Execute command argument if needed. if (!mEngine) { const QString commandArgument = getCommandArgument(); if (!commandArgument.isEmpty()) { Cli::CommandFormat format; Cli::executeCommand(commandArgument, &format); if (format == Cli::UriFormat) mustBeIconified = true; } } // Init engine content. mEngine = new QQmlApplicationEngine(); // Provide `+custom` folders for custom components and `5.9` for old components. { QStringList selectors("custom"); const QVersionNumber &version = QLibraryInfo::version(); if (version.majorVersion() == 5 && version.minorVersion() == 9) selectors.push_back("5.9"); (new QQmlFileSelector(mEngine, mEngine))->setExtraSelectors(selectors); } qInfo() << QStringLiteral("Activated selectors:") << QQmlFileSelector::get(mEngine)->selector()->allSelectors(); // Set modules paths. mEngine->addImportPath(":/ui/modules"); mEngine->addImportPath(":/ui/scripts"); mEngine->addImportPath(":/ui/views"); // Provide avatars/thumbnails providers. mEngine->addImageProvider(AvatarProvider::ProviderId, new AvatarProvider()); mEngine->addImageProvider(ImageProvider::ProviderId, new ImageProvider()); mEngine->addImageProvider(ExternalImageProvider::ProviderId, new ExternalImageProvider()); mEngine->addImageProvider(ThumbnailProvider::ProviderId, new ThumbnailProvider()); mEngine->rootContext()->setContextProperty("applicationUrl", APPLICATION_URL); registerTypes(); registerSharedTypes(); registerToolTypes(); registerSharedToolTypes(); // Enable notifications. mNotifier = new Notifier(mEngine); // Load main view. qInfo() << QStringLiteral("Loading main view..."); mEngine->load(QUrl(QmlViewMainWindow)); if (mEngine->rootObjects().isEmpty()) qFatal("Unable to open main window."); QObject::connect( CoreManager::getInstance()->getHandlers().get(), &CoreHandlers::coreStarted, [this, mustBeIconified]() { openAppAfterInit(mustBeIconified); } ); } // ----------------------------------------------------------------------------- QString App::getCommandArgument () { const QStringList &arguments = mParser->positionalArguments(); return arguments.empty() ? QString("") : arguments[0]; } // ----------------------------------------------------------------------------- #ifdef Q_OS_MACOS bool App::event (QEvent *event) { if (event->type() == QEvent::FileOpen) { const QString url = static_cast(event)->url().toString(); if (isSecondary()) { sendMessage(url.toLocal8Bit(), -1); ::exit(EXIT_SUCCESS); } Cli::executeCommand(url); } return SingleApplication::event(event); } #endif // ifdef Q_OS_MACOS // ----------------------------------------------------------------------------- QQuickWindow *App::getCallsWindow () const { if (CoreManager::getInstance()->getCore()->getConfig()->getInt( SettingsModel::UiSection, "disable_calls_window", 0 )) return nullptr; return mCallsWindow; } QQuickWindow *App::getMainWindow () const { return qobject_cast( const_cast(mEngine)->rootObjects().at(0) ); } QQuickWindow *App::getSettingsWindow () const { return mSettingsWindow; } // ----------------------------------------------------------------------------- void App::smartShowWindow (QQuickWindow *window) { if (!window) return; window->setVisible(true); // Force show, maybe redundant with setVisible if(window->visibility() == QWindow::Maximized)// Avoid to change visibility mode window->showMaximized(); else window->show(); window->raise();// Raise ensure to get focus on Mac window->requestActivate(); } // ----------------------------------------------------------------------------- bool App::hasFocus () const { return getMainWindow()->isActive() || (mCallsWindow && mCallsWindow->isActive()); } void App::stateChanged(Qt::ApplicationState pState) { DesktopTools::applicationStateChanged(pState); } // ----------------------------------------------------------------------------- void App::createParser () { delete mParser; mParser = new QCommandLineParser(); mParser->setApplicationDescription(tr("applicationDescription")); mParser->addPositionalArgument("command", tr("commandLineDescription").replace("%1", APPLICATION_NAME), "[command]"); mParser->addOptions({ { { "h", "help" }, tr("commandLineOptionHelp") }, { "cli-help", tr("commandLineOptionCliHelp").replace("%1", APPLICATION_NAME) }, { { "v", "version" }, tr("commandLineOptionVersion") }, { "config", tr("commandLineOptionConfig").replace("%1", EXECUTABLE_NAME), tr("commandLineOptionConfigArg") }, #ifndef Q_OS_MACOS { "iconified", tr("commandLineOptionIconified") }, #endif // ifndef Q_OS_MACOS { { "V", "verbose" }, tr("commandLineOptionVerbose") } }); } // ----------------------------------------------------------------------------- template static QObject *makeSharedSingleton (QQmlEngine *, QJSEngine *) { QObject *object = (*function)(); QQmlEngine::setObjectOwnership(object, QQmlEngine::CppOwnership); return object; } template static inline void registerSharedSingletonType (const char *name) { qmlRegisterSingletonType(MainQmlUri, 1, 0, name, makeSharedSingleton); } template static QObject *makeSharedSingleton (QQmlEngine *, QJSEngine *) { QObject *object = (CoreManager::getInstance()->*function)(); QQmlEngine::setObjectOwnership(object, QQmlEngine::CppOwnership); return object; } template static inline void registerSharedSingletonType (const char *name) { qmlRegisterSingletonType(MainQmlUri, 1, 0, name, makeSharedSingleton); } template static inline void registerUncreatableType (const char *name) { qmlRegisterUncreatableType(MainQmlUri, 1, 0, name, QLatin1String("Uncreatable")); } template static inline void registerSingletonType (const char *name) { qmlRegisterSingletonType(MainQmlUri, 1, 0, name, [](QQmlEngine *engine, QJSEngine *) -> QObject *{ return new T(engine); }); } template static inline void registerType (const char *name) { qmlRegisterType(MainQmlUri, 1, 0, name); } template static inline void registerToolType (const char *name) { qmlRegisterSingletonType(name, 1, 0, name, [](QQmlEngine *engine, QJSEngine *) -> QObject *{ return new T(engine); }); } template static QObject *makeSharedTool (QQmlEngine *, QJSEngine *) { QObject *object = (Owner::getInstance()->*function)(); QQmlEngine::setObjectOwnership(object, QQmlEngine::CppOwnership); return object; } template static inline void registerSharedToolType (const char *name) { qmlRegisterSingletonType(name, 1, 0, name, makeSharedTool); } void App::registerTypes () { qInfo() << QStringLiteral("Registering types..."); qRegisterMetaType>(); qRegisterMetaType(); registerType("AssistantModel"); registerType("AuthenticationNotifier"); registerType("CallsListProxyModel"); registerType("Camera"); registerType("CameraPreview"); registerType("ChatProxyModel"); registerType("ConferenceHelperModel"); registerType("ConferenceModel"); registerType("ContactsListProxyModel"); registerType("FileDownloader"); registerType("FileExtractor"); registerType("HistoryProxyModel"); registerType("SipAddressesProxyModel"); registerType("SoundPlayer"); registerType("TelephoneNumbersModel"); registerSingletonType("AudioCodecsModel"); registerSingletonType("OwnPresenceModel"); registerSingletonType("Presence"); registerSingletonType("TimelineModel"); registerSingletonType("UrlHandlers"); registerSingletonType("VideoCodecsModel"); registerUncreatableType("CallModel"); registerUncreatableType("ChatModel"); registerUncreatableType("ConferenceAddModel"); registerUncreatableType("ContactModel"); registerUncreatableType("HistoryModel"); registerUncreatableType("SipAddressObserver"); registerUncreatableType("VcardModel"); } void App::registerSharedTypes () { qInfo() << QStringLiteral("Registering shared types..."); registerSharedSingletonType("App"); registerSharedSingletonType("CoreManager"); registerSharedSingletonType("SettingsModel"); registerSharedSingletonType("AccountSettingsModel"); registerSharedSingletonType("SipAddressesModel"); registerSharedSingletonType("CallsListModel"); registerSharedSingletonType("ContactsListModel"); } void App::registerToolTypes () { qInfo() << QStringLiteral("Registering tool types..."); registerToolType("Clipboard"); registerToolType("DesktopTools"); registerToolType("TextToSpeech"); registerToolType("Units"); } void App::registerSharedToolTypes () { qInfo() << QStringLiteral("Registering shared tool types..."); registerSharedToolType("Colors"); } // ----------------------------------------------------------------------------- void App::setTrayIcon () { QQuickWindow *root = getMainWindow(); QSystemTrayIcon *systemTrayIcon = new QSystemTrayIcon(mEngine); // trayIcon: Right click actions. QAction *settingsAction = new QAction(tr("settings"), root); root->connect(settingsAction, &QAction::triggered, root, [this] { App::smartShowWindow(getSettingsWindow()); }); QAction *aboutAction = new QAction(tr("about"), root); root->connect(aboutAction, &QAction::triggered, root, [root] { App::smartShowWindow(root); QMetaObject::invokeMethod( root, AttachVirtualWindowMethodName, Qt::DirectConnection, Q_ARG(QVariant, QUrl(AboutPath)), Q_ARG(QVariant, QVariant()), Q_ARG(QVariant, QVariant()) ); }); QAction *restoreAction = new QAction(tr("restore"), root); root->connect(restoreAction, &QAction::triggered, root, [root] { smartShowWindow(root); }); QAction *quitAction = new QAction(tr("quit"), root); root->connect(quitAction, &QAction::triggered, this, &App::quit); // trayIcon: Left click actions. QMenu *menu = new QMenu(); root->connect(systemTrayIcon, &QSystemTrayIcon::activated, [root]( QSystemTrayIcon::ActivationReason reason ) { if (reason == QSystemTrayIcon::Trigger) { if (root->visibility() == QWindow::Hidden) smartShowWindow(root); else root->hide(); } }); menu->setTitle(APPLICATION_NAME); // Build trayIcon menu. menu->addAction(settingsAction); menu->addAction(aboutAction); menu->addSeparator(); menu->addAction(restoreAction); menu->addSeparator(); menu->addAction(quitAction); systemTrayIcon->setContextMenu(menu); systemTrayIcon->setIcon(QIcon(LinphoneUtils::WindowIconPath)); systemTrayIcon->setToolTip(APPLICATION_NAME); systemTrayIcon->show(); mSystemTrayIcon = systemTrayIcon; if(!QSystemTrayIcon::isSystemTrayAvailable()) qInfo() << "System tray is not available"; } // ----------------------------------------------------------------------------- void App::initLocale (const shared_ptr &config) { // Try to use preferred locale. QString locale; // Use english. This default translator is used if there are no found translations in others loads mLocale = DefaultLocale; if (!installLocale(*this, *mDefaultTranslator, QLocale(mLocale))) qFatal("Unable to install default translator."); if (config) locale = Utils::coreStringToAppString(config->getString(SettingsModel::UiSection, "locale", "")); if (!locale.isEmpty() && installLocale(*this, *mTranslator, QLocale(locale))) { mLocale = locale; return; } // Try to use system locale. QLocale sysLocale = QLocale::system(); if (installLocale(*this, *mTranslator, sysLocale)) { mLocale = sysLocale.name(); return; } } QString App::getConfigLocale () const { return Utils::coreStringToAppString( CoreManager::getInstance()->getCore()->getConfig()->getString( SettingsModel::UiSection, "locale", "" ) ); } void App::setConfigLocale (const QString &locale) { CoreManager::getInstance()->getCore()->getConfig()->setString( SettingsModel::UiSection, "locale", Utils::appStringToCoreString(locale) ); emit configLocaleChanged(locale); } QString App::getLocale () const { return mLocale; } // ----------------------------------------------------------------------------- #ifdef Q_OS_LINUX void App::setAutoStart (bool enabled) { if (enabled == mAutoStart) return; QDir dir(AutoStartDirectory); if (!dir.exists() && !dir.mkpath(AutoStartDirectory)) { qWarning() << QStringLiteral("Unable to build autostart dir path: `%1`.").arg(AutoStartDirectory); return; } const QString confPath(AutoStartDirectory + EXECUTABLE_NAME ".desktop"); qInfo() << QStringLiteral("Updating `%1`...").arg(confPath); QFile file(confPath); if (!enabled) { if (file.exists() && !file.remove()) { qWarning() << QLatin1String("Unable to remove autostart file: `" EXECUTABLE_NAME ".desktop`."); return; } mAutoStart = enabled; emit autoStartChanged(enabled); return; } if (!file.open(QFile::WriteOnly)) { qWarning() << "Unable to open autostart file: `" EXECUTABLE_NAME ".desktop`."; return; } const QString binPath(applicationFilePath()); const QString exec( binPath.startsWith("/app") ? QStringLiteral("flatpak run " APPLICATION_ID) : binPath ); QTextStream(&file) << QString( "[Desktop Entry]\n" "Name=" APPLICATION_NAME "\n" "GenericName=SIP Phone\n" "Comment=" APPLICATION_DESCRIPTION "\n" "Type=Application\n" "Exec=" + exec + "\n" "Icon=\n" "Terminal=false\n" "Categories=Network;Telephony;\n" "MimeType=x-scheme-handler/sip-linphone;x-scheme-handler/sip;x-scheme-handler/sips-linphone;x-scheme-handler/sips;x-scheme-handler/tel;x-scheme-handler/callto;\n" ); mAutoStart = enabled; emit autoStartChanged(enabled); } #elif defined(Q_OS_MACOS) void App::setAutoStart (bool enabled) { if (enabled == mAutoStart) return; if (getMacOsBundlePath().isEmpty()) { qWarning() << QStringLiteral("Application is not installed. Unable to change autostart state."); return; } if (enabled) QProcess::execute(OsascriptExecutable, { "-e", "tell application \"System Events\" to make login item at end with properties" "{ path: \"" + getMacOsBundlePath() + "\", hidden: false }" }); else QProcess::execute(OsascriptExecutable, { "-e", "tell application \"System Events\" to delete login item \"" + getMacOsBundleName() + "\"" }); mAutoStart = enabled; emit autoStartChanged(enabled); } #else void App::setAutoStart (bool enabled) { if (enabled == mAutoStart) return; QSettings settings(AutoStartSettingsFilePath, QSettings::NativeFormat); if (enabled) settings.setValue(EXECUTABLE_NAME, QDir::toNativeSeparators(applicationFilePath())); else settings.remove(EXECUTABLE_NAME); mAutoStart = enabled; emit autoStartChanged(enabled); } #endif // ifdef Q_OS_LINUX // ----------------------------------------------------------------------------- void App::openAppAfterInit (bool mustBeIconified) { qInfo() << QStringLiteral("Open " APPLICATION_NAME " app."); // Create other windows. mCallsWindow = createSubWindow(mEngine, QmlViewCallsWindow); mSettingsWindow = createSubWindow(mEngine, QmlViewSettingsWindow); QObject::connect(mSettingsWindow, &QWindow::visibilityChanged, this, [](QWindow::Visibility visibility) { if (visibility == QWindow::Hidden) { qInfo() << QStringLiteral("Update nat policy."); shared_ptr core = CoreManager::getInstance()->getCore(); core->setNatPolicy(core->getNatPolicy()); } }); QQuickWindow *mainWindow = getMainWindow(); #ifndef __APPLE__ // Enable TrayIconSystem. if (!QSystemTrayIcon::isSystemTrayAvailable()) qWarning("System tray not found on this system."); else setTrayIcon(); if (!mustBeIconified) smartShowWindow(mainWindow); #else Q_UNUSED(mustBeIconified); smartShowWindow(mainWindow); #endif // ifndef __APPLE__ // Display Assistant if it does not exist proxy config. if (CoreManager::getInstance()->getCore()->getProxyConfigList().empty()) QMetaObject::invokeMethod(mainWindow, "setView", Q_ARG(QVariant, AssistantViewName), Q_ARG(QVariant, QString(""))); #ifdef ENABLE_UPDATE_CHECK QTimer *timer = new QTimer(mEngine); timer->setInterval(VersionUpdateCheckInterval); QObject::connect(timer, &QTimer::timeout, this, &App::checkForUpdate); timer->start(); checkForUpdate(); #endif // ifdef ENABLE_UPDATE_CHECK setOpened(true); } // ----------------------------------------------------------------------------- QString App::getStrippedApplicationVersion(){// x.y.z but if 'z-*' then x.y.z-1 QString currentVersion = applicationVersion(); QStringList versions = currentVersion.split('.'); if(versions.size() >=3){ currentVersion = versions[0]+"."+versions[1]+"."; QStringList patchVersions = versions[2].split('-'); if( patchVersions.size() > 1) currentVersion += QString::number(patchVersions[0].toInt()-1); else currentVersion += patchVersions[0]; } return currentVersion; } void App::checkForUpdate () { CoreManager::getInstance()->getCore()->checkForUpdate( Utils::appStringToCoreString(getStrippedApplicationVersion()) ); } linphone-desktop-4.2.5/linphone-app/src/app/App.hpp000066400000000000000000000101701376717241300222110ustar00rootroot00000000000000/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef APP_H_ #define APP_H_ #include #include "single-application/SingleApplication.hpp" // ============================================================================= class QCommandLineParser; class QQmlApplicationEngine; class QQuickWindow; class QSystemTrayIcon; namespace linphone { class Config; } class Colors; class DefaultTranslator; class Notifier; class App : public SingleApplication { Q_OBJECT; Q_PROPERTY(QString configLocale READ getConfigLocale WRITE setConfigLocale NOTIFY configLocaleChanged); Q_PROPERTY(QString locale READ getLocale CONSTANT); Q_PROPERTY(QVariantList availableLocales READ getAvailableLocales CONSTANT); Q_PROPERTY(QString qtVersion READ getQtVersion CONSTANT); Q_PROPERTY(bool autoStart READ getAutoStart WRITE setAutoStart NOTIFY autoStartChanged); public: App (int &argc, char *argv[]); ~App (); void initContentApp (); QString getCommandArgument (); #ifdef Q_OS_MACOS bool event (QEvent *event) override; #endif // ifdef Q_OS_MACOS QQmlApplicationEngine *getEngine () { return mEngine; } Notifier *getNotifier () const { return mNotifier; } Colors *getColors () const { return mColors; } QSystemTrayIcon *getSystemTrayIcon () const { return mSystemTrayIcon; } QQuickWindow *getMainWindow () const; bool hasFocus () const; bool isOpened () const { return mIsOpened; } static App *getInstance () { return static_cast(QApplication::instance()); } static constexpr int RestartCode = 1000; Q_INVOKABLE void restart () { exit(RestartCode); } Q_INVOKABLE QQuickWindow *getCallsWindow () const; Q_INVOKABLE QQuickWindow *getSettingsWindow () const; Q_INVOKABLE static void smartShowWindow (QQuickWindow *window); public slots: void stateChanged(Qt::ApplicationState); signals: void configLocaleChanged (const QString &locale); void autoStartChanged (bool enabled); void opened (bool status); private: void createParser (); void registerTypes (); void registerSharedTypes (); void registerToolTypes (); void registerSharedToolTypes (); void setTrayIcon (); void createNotifier (); void initLocale (const std::shared_ptr &config); QString getConfigLocale () const; void setConfigLocale (const QString &locale); QString getLocale () const; QVariantList getAvailableLocales () const { return mAvailableLocales; } bool getAutoStart () const { return mAutoStart; } void setAutoStart (bool enabled); void openAppAfterInit (bool mustBeIconified = false); void setOpened (bool status) { if (mIsOpened != status) { mIsOpened = status; emit opened(mIsOpened); } } static QString getStrippedApplicationVersion();// x.y.z but if 'z-*' then x.y.z-1 static void checkForUpdate (); static QString getQtVersion () { return qVersion(); } QVariantList mAvailableLocales; QString mLocale; bool mAutoStart = false; QCommandLineParser *mParser = nullptr; QQmlApplicationEngine *mEngine = nullptr; DefaultTranslator *mTranslator = nullptr; DefaultTranslator *mDefaultTranslator = nullptr; Notifier *mNotifier = nullptr; QQuickWindow *mCallsWindow = nullptr; QQuickWindow *mSettingsWindow = nullptr; Colors *mColors = nullptr; QSystemTrayIcon *mSystemTrayIcon = nullptr; bool mIsOpened = false; }; #endif // APP_H_ linphone-desktop-4.2.5/linphone-app/src/app/AppController.cpp000066400000000000000000000062401376717241300242530ustar00rootroot00000000000000/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include #include #include #include #include "config.h" #include "gitversion.h" #include "AppController.hpp" #include "components/other/desktop-tools/DesktopTools.hpp" // ============================================================================= using namespace std; namespace { constexpr char ApplicationMinimalQtVersion[] = "5.9.0"; constexpr char DefaultFont[] = "Noto Sans"; } AppController::AppController (int &argc, char *argv[]) { DesktopTools::init(); QT_REQUIRE_VERSION(argc, argv, ApplicationMinimalQtVersion) Q_ASSERT(!mApp); // Disable QML cache. Avoid malformed cache. qputenv("QML_DISABLE_DISK_CACHE", "true"); QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); // Useful to share camera on Fullscreen (other context) QApplication::setAttribute(Qt::AA_ShareOpenGLContexts); // Do not use APPLICATION_NAME here. // The EXECUTABLE_NAME will be used in qt standard paths. It's our goal. QCoreApplication::setApplicationName(EXECUTABLE_NAME); QApplication::setOrganizationDomain(EXECUTABLE_NAME); QCoreApplication::setApplicationVersion(LINPHONE_QT_GIT_VERSION); mApp = new App(argc, argv); // --------------------------------------------------------------------------- // App creation. // --------------------------------------------------------------------------- QQuickStyle::setStyle("Default"); if (mApp->isSecondary()) { #ifdef Q_OS_MACOS mApp->processEvents(); #endif // ifdef Q_OS_MACOS QString command = mApp->getCommandArgument(); mApp->sendMessage(command.isEmpty() ? "show" : command.toLocal8Bit(), -1); return; } // --------------------------------------------------------------------------- // Fonts. // --------------------------------------------------------------------------- QDirIterator it(":", QDirIterator::Subdirectories); while (it.hasNext()) { QFileInfo info(it.next()); if (info.suffix() == QLatin1String("ttf") || info.suffix() == QLatin1String("otf")) { QString path = info.absoluteFilePath(); if (path.startsWith(":/assets/fonts/")) if(QFontDatabase::addApplicationFont(path)<0) qWarning() << "Font cannot load : " << path; } } qInfo() << "Available fonts : " << QFontDatabase().families(); mApp->setFont(QFont(DefaultFont)); } AppController::~AppController () { delete mApp; } linphone-desktop-4.2.5/linphone-app/src/app/AppController.hpp000066400000000000000000000022321376717241300242550ustar00rootroot00000000000000/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef APP_CONTROLLER_H_ #define APP_CONTROLLER_H_ #include "App.hpp" // ============================================================================= class AppController { public: AppController (int &argc, char *argv[]); ~AppController (); App *getApp () const { Q_CHECK_PTR(mApp); return mApp; } private: App *mApp = nullptr; }; #endif // APP_CONTROLLER_H_ linphone-desktop-4.2.5/linphone-app/src/app/cli/000077500000000000000000000000001376717241300215305ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/src/app/cli/Cli.cpp000066400000000000000000000365211376717241300227520ustar00rootroot00000000000000/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include #include #include "config.h" #include "app/App.hpp" #include "components/calls/CallsListModel.hpp" #include "components/core/CoreHandlers.hpp" #include "components/core/CoreManager.hpp" #include "components/settings/SettingsModel.hpp" #include "utils/Utils.hpp" #include "Cli.hpp" // ============================================================================= using namespace std; // ============================================================================= // API. // ============================================================================= static void cliShow (QHash &) { App *app = App::getInstance(); app->smartShowWindow(app->getMainWindow()); } static void cliCall (QHash &args) { CoreManager::getInstance()->getCallsListModel()->launchAudioCall(args["sip-address"]); } static void cliJoinConference (QHash &args) { const QString sipAddress = args.take("sip-address"); CoreManager *coreManager = CoreManager::getInstance(); const shared_ptr core = coreManager->getCore(); { shared_ptr address = core->createPrimaryContactParsed(); address->setDisplayName(Utils::appStringToCoreString(args.take("display-name"))); core->setPrimaryContact(address->asString()); } args["method"] = QStringLiteral("join-conference"); coreManager->getCallsListModel()->launchAudioCall(sipAddress, args); } static void cliJoinConferenceAs (QHash &args) { const QString fromSipAddress = args.take("guest-sip-address"); const QString toSipAddress = args.take("sip-address"); CoreManager *coreManager = CoreManager::getInstance(); shared_ptr proxyConfig = coreManager->getCore()->getDefaultProxyConfig(); if (!proxyConfig) { qWarning() << QStringLiteral("You have no proxy config."); return; } const shared_ptr currentSipAddress = proxyConfig->getIdentityAddress(); const shared_ptr askedSipAddress = linphone::Factory::get()->createAddress( Utils::appStringToCoreString(fromSipAddress) ); if (!currentSipAddress->weakEqual(askedSipAddress)) { qWarning() << QStringLiteral("Guest sip address `%1` doesn't match with default proxy config.") .arg(fromSipAddress); return; } args["method"] = QStringLiteral("join-conference"); coreManager->getCallsListModel()->launchAudioCall(toSipAddress, args); } static void cliInitiateConference (QHash &args) { shared_ptr core = CoreManager::getInstance()->getCore(); // Check identity. { shared_ptr address = core->interpretUrl(Utils::appStringToCoreString(args["sip-address"])); if (!address || address->getUsername().empty()) { qWarning() << QStringLiteral("Unable to parse invalid sip address."); return; } address->clean(); shared_ptr proxyConfig = core->getDefaultProxyConfig(); if (!proxyConfig) { qWarning() << QStringLiteral("Not connected to a proxy config"); return; } if (!proxyConfig->getIdentityAddress()->weakEqual(address)) { qWarning() << QStringLiteral("Received different sip address from identity : `%1 != %2`.") .arg(Utils::coreStringToAppString(proxyConfig->getIdentityAddress()->asString())) .arg(Utils::coreStringToAppString(address->asString())); return; } } shared_ptr conference = core->getConference(); const QString id = args["conference-id"]; auto updateCallsWindow = []() { QQuickWindow *callsWindow = App::getInstance()->getCallsWindow(); if (!callsWindow) return; // TODO: Set the view to the "waiting call view". if (CoreManager::getInstance()->getSettingsModel()->getKeepCallsWindowInBackground()) { if (!callsWindow->isVisible()) callsWindow->showMinimized(); } else App::smartShowWindow(callsWindow); }; if (conference) { if (conference->getId() == Utils::appStringToCoreString(id)) { qInfo() << QStringLiteral("Conference `%1` already exists.").arg(id); updateCallsWindow(); return; } qInfo() << QStringLiteral("Remove existing conference with id: `%1`.") .arg(Utils::coreStringToAppString(conference->getId())); core->terminateConference(); } qInfo() << QStringLiteral("Create conference with id: `%1`.").arg(id); auto confParameters = core->createConferenceParams(); confParameters->enableVideo(false);// Video is not yet fully supported by the application in conference conference = core->createConferenceWithParams(confParameters); conference->setId(Utils::appStringToCoreString(id)); if (core->enterConference() == -1) { qWarning() << QStringLiteral("Unable to join created conference: `%1`.").arg(id); return; } updateCallsWindow(); } // ============================================================================= // Helpers. // ============================================================================= static QString splitWord (QString word, int &curPos, const int lineLength, const QString &padding) { QString out; out += word.mid(0, lineLength - curPos) + "\n" + padding; curPos = padding.length(); word = word.mid(lineLength - curPos); while (word.length() > lineLength - curPos) { out += word.mid(0, lineLength - curPos); word = word.mid(lineLength - curPos); out += "\n" + padding; } out += word; curPos = word.length() + padding.length(); return out; } static QString indentedWord (QString word, int &curPos, const int lineLength, const QString &padding) { QString out; if (curPos + word.length() > lineLength) { if (padding.length() + word.length() > lineLength) { out += splitWord(word, curPos, lineLength, padding); } else { out += QStringLiteral("\n"); out += padding + word; curPos = padding.length(); } } else { out += word; curPos += word.length(); } return out; } static string multilineIndent (const QString &str, int indentationNumber = 0) { constexpr int lineLength(80); static const QRegExp spaceRegexp("(\\s)"); const QString padding(indentationNumber * 2, ' '); QString out = padding; int indentedTextCurPos = padding.length(); int spacePos = 0; int wordPos = spacePos; QString word; while ((spacePos = spaceRegexp.indexIn(str, spacePos)) != -1) { word = str.mid(wordPos, spacePos - wordPos); out += indentedWord(word, indentedTextCurPos, lineLength, padding); switch (str[spacePos].unicode()) { case '\n': out += "\n" + padding; indentedTextCurPos = padding.length(); break; case '\t': // TAB as space. case ' ': if (indentedTextCurPos == lineLength) { out += "\n" + padding; indentedTextCurPos = padding.length(); } else { out += " "; indentedTextCurPos += 1; } break; default: break; } spacePos += 1; wordPos = spacePos; } word = str.mid(wordPos); out += indentedWord(word, indentedTextCurPos, lineLength, padding); out += "\n"; return Utils::appStringToCoreString(out); } // ============================================================================= Cli::Command::Command ( const QString &functionName, const char *functionDescription, Cli::Function function, const QHash &argsScheme ) : mFunctionName(functionName), mFunctionDescription(functionDescription), mFunction(function), mArgsScheme(argsScheme) {} void Cli::Command::execute (QHash &args) const { // Check arguments validity. for (const auto &argName : args.keys()) { if (!mArgsScheme.contains(argName)) { qWarning() << QStringLiteral("Command with invalid argument: `%1 (%2)`.") .arg(mFunctionName).arg(argName); return; } } // Check missing arguments. for (const auto &argName : mArgsScheme.keys()) { if (!mArgsScheme[argName].isOptional && (!args.contains(argName) || args[argName].isEmpty())) { qWarning() << QStringLiteral("Missing argument for command: `%1 (%2)`.") .arg(mFunctionName).arg(argName); return; } } // Execute! App *app = App::getInstance(); if (app->isOpened()) { qInfo() << QStringLiteral("Execute command:") << args; (*mFunction)(args); } else { Function f = mFunction; Utils::connectOnce(app, &App::opened, app, [f, args] { qInfo() << QStringLiteral("Execute deferred command:") << args; QHash fuckConst = args; (*f)(fuckConst); }); } } void Cli::Command::executeUri (const shared_ptr &address) const { QHash args; // TODO: check if there is too much headers. for (const auto &argName : mArgsScheme.keys()) { const string header = address->getHeader(Utils::appStringToCoreString(argName)); args[argName] = QByteArray::fromBase64(QByteArray(header.c_str(), int(header.length()))); } address->clean(); args["sip-address"] = Utils::coreStringToAppString(address->asStringUriOnly()); execute(args); } QString Cli::Command::getFunctionSyntax () const { QString functionSyntax; functionSyntax += QStringLiteral("\""); functionSyntax += mFunctionName; for (auto &argName : mArgsScheme.keys()){ functionSyntax += QStringLiteral(" "); functionSyntax += mArgsScheme[argName].isOptional ? QStringLiteral("[") : QStringLiteral(""); functionSyntax += argName; functionSyntax += QStringLiteral("=<"); switch (mArgsScheme[argName].type) { case String: functionSyntax += QStringLiteral("str"); break; default: functionSyntax += QStringLiteral("value"); break; } functionSyntax += QString(">"); functionSyntax += mArgsScheme[argName].isOptional ? QStringLiteral("]") : QStringLiteral(""); } functionSyntax += QStringLiteral("\""); return functionSyntax; } // ============================================================================= // FIXME: Do not accept args without value like: cmd toto. // In the future `toto` could be a boolean argument. QRegExp Cli::mRegExpArgs("(?:(?:([\\w-]+)\\s*)=\\s*(?:\"([^\"\\\\]*(?:\\\\.[^\"\\\\]*)*)\"|([^\\s]+)\\s*))"); QRegExp Cli::mRegExpFunctionName("^\\s*([a-z-]+)\\s*"); QMap Cli::mCommands = { createCommand("show", QT_TR_NOOP("showFunctionDescription"), cliShow), createCommand("call", QT_TR_NOOP("callFunctionDescription"), cliCall, { { "sip-address", {} } }), createCommand("initiate-conference", QT_TR_NOOP("initiateConferenceFunctionDescription"), cliInitiateConference, { { "sip-address", {} }, { "conference-id", {} } }), createCommand("join-conference", QT_TR_NOOP("joinConferenceFunctionDescription"), cliJoinConference, { { "sip-address", {} }, { "conference-id", {} }, { "display-name", {} } }), createCommand("join-conference-as", QT_TR_NOOP("joinConferenceAsFunctionDescription"), cliJoinConferenceAs, { { "sip-address", {} }, { "conference-id", {} }, { "guest-sip-address", {} } }) }; // ----------------------------------------------------------------------------- void Cli::executeCommand (const QString &command, CommandFormat *format) { shared_ptr address = linphone::Factory::get()->createAddress( Utils::appStringToCoreString(command) ); // Execute cli command. if (!address) { qInfo() << QStringLiteral("Detecting cli command: `%1`...").arg(command); const QString &functionName = parseFunctionName(command); if (!functionName.isEmpty()) { QHash args = parseArgs(command); mCommands[functionName].execute(args); } if (format) *format = CliFormat; return; } if (format) *format = UriFormat; // Execute uri command. qInfo() << QStringLiteral("Detecting uri command: `%1`...").arg(command); if (address->getUsername().empty()) { qWarning() << QStringLiteral("Failed to execute command. No username given."); return; } string scheme = address->getScheme(); for (const string &validScheme : { "sip", "sip-linphone", "sips", "sips-linphone", "tel", "callto" }) if (scheme == validScheme) goto success; qWarning() << QStringLiteral("Not a valid uri: `%1` Unsupported scheme: `%2`.") .arg(command).arg(Utils::coreStringToAppString(scheme)); return; success: const QString functionName = Utils::coreStringToAppString(address->getHeader("method")).isEmpty() ? QStringLiteral("call") : Utils::coreStringToAppString(address->getHeader("method")); if (!functionName.isEmpty() && !mCommands.contains(functionName)) { qWarning() << QStringLiteral("This command doesn't exist: `%1`.").arg(functionName); return; } mCommands[functionName].executeUri(address); } void Cli::showHelp () { cout << multilineIndent(tr("appCliDescription").arg(APPLICATION_NAME), 0) << endl << "Usage: " << endl << multilineIndent(tr("uriCommandLineSyntax").arg(EXECUTABLE_NAME), 0) << multilineIndent(tr("cliCommandLineSyntax").arg(EXECUTABLE_NAME), 0) << endl << multilineIndent(tr("commandsName")) << endl; for (const auto &method : mCommands.keys()) cout << multilineIndent(mCommands[method].getFunctionSyntax(), 1) << multilineIndent(tr(mCommands[method].getFunctionDescription()), 2) << endl; } // ----------------------------------------------------------------------------- pair Cli::createCommand ( const QString &functionName, const char *functionDescription, Function function, const QHash &argsScheme ) { return { functionName, Cli::Command(functionName, functionDescription, function, argsScheme) }; } // ----------------------------------------------------------------------------- QString Cli::parseFunctionName (const QString &command) { mRegExpFunctionName.indexIn(command); if (mRegExpFunctionName.pos(1) == -1) { qWarning() << QStringLiteral("Unable to parse function name of command: `%1`.").arg(command); return QString(""); } const QStringList texts = mRegExpFunctionName.capturedTexts(); const QString functionName = texts[1]; if (!mCommands.contains(functionName)) { qWarning() << QStringLiteral("This command doesn't exist: `%1`.").arg(functionName); return QString(""); } return functionName; } QHash Cli::parseArgs (const QString &command) { QHash args; int pos = 0; while ((pos = mRegExpArgs.indexIn(command, pos)) != -1) { pos += mRegExpArgs.matchedLength(); args[mRegExpArgs.cap(1)] = (mRegExpArgs.cap(2).isEmpty() ? mRegExpArgs.cap(3) : mRegExpArgs.cap(2)); } return args; } linphone-desktop-4.2.5/linphone-app/src/app/cli/Cli.hpp000066400000000000000000000052531376717241300227550ustar00rootroot00000000000000/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef CLI_H_ #define CLI_H_ #include #include #include #include // ============================================================================= namespace linphone { class Address; } class Cli : public QObject { Q_OBJECT; typedef void (*Function)(QHash &); enum ArgumentType { String }; struct Argument { Argument (ArgumentType type = String, bool isOptional = false) { this->type = type; this->isOptional = isOptional; } ArgumentType type; bool isOptional; }; class Command { public: Command () = default; Command ( const QString &functionName, const char *functionDescription, Function function, const QHash &argsScheme ); void execute (QHash &args) const; void executeUri (const std::shared_ptr &address) const; const char *getFunctionDescription () const { return mFunctionDescription; } QString getFunctionSyntax () const ; private: QString mFunctionName; const char *mFunctionDescription; Function mFunction = nullptr; QHash mArgsScheme; }; public: enum CommandFormat { UnknownFormat, CliFormat, UriFormat }; static void executeCommand (const QString &command, CommandFormat *format = nullptr); static void showHelp (); private: Cli (); static std::pair createCommand ( const QString &functionName, const char *functionDescription, Function function, const QHash &argsScheme = QHash() ); static QString parseFunctionName (const QString &command); static QHash parseArgs (const QString &command); static QMap mCommands; static QRegExp mRegExpArgs; static QRegExp mRegExpFunctionName; }; #endif // CLI_H_ linphone-desktop-4.2.5/linphone-app/src/app/logger/000077500000000000000000000000001376717241300222405ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/src/app/logger/Logger.cpp000066400000000000000000000144161376717241300241710ustar00rootroot00000000000000/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include #include #include #include #include #include "config.h" #include "components/settings/SettingsModel.hpp" #include "utils/Utils.hpp" #include "Logger.hpp" // ============================================================================= #if defined(__linux__) || defined(__APPLE__) #define BLUE "\x1B[1;34m" #define YELLOW "\x1B[1;33m" #define GREEN "\x1B[1;32m" #define PURPLE "\x1B[1;35m" #define RED "\x1B[1;31m" #define RESET "\x1B[0m" #else #define BLUE "" #define YELLOW "" #define GREEN "" #define PURPLE "" #define RED "" #define RESET "" #endif // if defined(__linux__) || defined(__APPLE__) using namespace std; namespace { constexpr char QtDomain[] = "qt"; constexpr size_t MaxLogsCollectionSize = 10485760; // 10MB. constexpr char SrcPattern[] = "/src/"; } QMutex Logger::mMutex; Logger *Logger::mInstance; // ----------------------------------------------------------------------------- static inline QByteArray getFormattedCurrentTime () { return QDateTime::currentDateTime().toString("HH:mm:ss:zzz").toLocal8Bit(); } // ----------------------------------------------------------------------------- class LinphoneLogger : public linphone::LoggingServiceListener { public: LinphoneLogger (const Logger *logger) : mLogger(logger) {} private: void onLogMessageWritten ( const shared_ptr &, const string &domain, linphone::LogLevel level, const string &message ) override { if (!mLogger->isVerbose()) return; using LogLevel = linphone::LogLevel; const char *format; switch (level) { case LogLevel::Debug: format = GREEN "[%s][Debug]" YELLOW "Core:%s: " RESET "%s\n"; break; case LogLevel::Trace: format = BLUE "[%s][Trace]" YELLOW "Core:%s: " RESET "%s\n"; break; case LogLevel::Message: format = BLUE "[%s][Info]" YELLOW "Core:%s: " RESET "%s\n"; break; case LogLevel::Warning: format = RED "[%s][Warning]" YELLOW "Core:%s: " RESET "%s\n"; break; case LogLevel::Error: format = RED "[%s][Error]" YELLOW "Core:%s: " RESET "%s\n"; break; case LogLevel::Fatal: format = RED "[%s][Fatal]" YELLOW "Core:%s: " RESET "%s\n"; break; } fprintf( stderr, format, getFormattedCurrentTime().constData(), domain.empty() ? domain.c_str() : EXECUTABLE_NAME, message.c_str() ); if (level == LogLevel::Fatal) terminate(); }; const Logger *mLogger; }; // ----------------------------------------------------------------------------- void Logger::log (QtMsgType type, const QMessageLogContext &context, const QString &msg) { const char *format; BctbxLogLevel level; if (type == QtDebugMsg) { format = GREEN "[%s][%p][Debug]" PURPLE "%s" RESET "%s\n"; level = BCTBX_LOG_DEBUG; } else if (type == QtInfoMsg) { format = BLUE "[%s][%p][Info]" PURPLE "%s" RESET "%s\n"; level = BCTBX_LOG_MESSAGE; } else if (type == QtWarningMsg) { format = RED "[%s][%p][Warning]" PURPLE "%s" RESET "%s\n"; level = BCTBX_LOG_WARNING; } else if (type == QtCriticalMsg) { format = RED "[%s][%p][Critical]" PURPLE "%s" RESET "%s\n"; level = BCTBX_LOG_ERROR; } else if (type == QtFatalMsg) { format = RED "[%s][%p][Fatal]" PURPLE "%s" RESET "%s\n"; level = BCTBX_LOG_FATAL; } else return; const char *contextStr = ""; #ifdef QT_MESSAGELOGCONTEXT QByteArray contextArr; { const char *file = context.file; const char *pos = file ? Utils::rstrstr(file, SrcPattern) : file; contextArr = QStringLiteral("%1:%2: ") .arg(pos ? pos + sizeof(SrcPattern) - 1 : file) .arg(context.line) .toLocal8Bit(); contextStr = contextArr.constData(); } #else Q_UNUSED(context); #endif // ifdef QT_MESSAGELOGCONTEXT QByteArray localMsg = msg.toLocal8Bit(); QByteArray dateTime = getFormattedCurrentTime(); mMutex.lock(); fprintf(stdout, format, dateTime.constData(), QThread::currentThread(), contextStr, localMsg.constData()); if( level == BCTBX_LOG_FATAL) QMessageBox::critical(nullptr, "Linphone will crash", msg); // Print an error message before sending msg to bctoolbox bctbx_log(QtDomain, level, "QT: %s%s", contextStr, localMsg.constData()); mMutex.unlock(); if (type == QtFatalMsg) terminate(); } // ----------------------------------------------------------------------------- void Logger::enable (bool status) { linphone::Core::enableLogCollection( status ? linphone::LogCollectionState::Enabled : linphone::LogCollectionState::Disabled ); } void Logger::init (const shared_ptr &config) { if (mInstance) return; const QString folder = SettingsModel::getLogsFolder(config); Q_ASSERT(!folder.isEmpty()); mInstance = new Logger(); qInstallMessageHandler(Logger::log); { shared_ptr loggingService = mInstance->mLoggingService = linphone::LoggingService::get(); loggingService->setDomain(QtDomain); loggingService->setLogLevel(linphone::LogLevel::Message); loggingService->addListener(make_shared(mInstance)); } linphone::Core::setLogCollectionPath(Utils::appStringToCoreString(folder)); linphone::Core::setLogCollectionPrefix(EXECUTABLE_NAME); linphone::Core::setLogCollectionMaxFileSize(MaxLogsCollectionSize); mInstance->enable(SettingsModel::getLogsEnabled(config)); } linphone-desktop-4.2.5/linphone-app/src/app/logger/Logger.hpp000066400000000000000000000031071376717241300241710ustar00rootroot00000000000000/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef LOGGER_H_ #define LOGGER_H_ #include #include // ============================================================================= namespace linphone { class Config; class LoggingService; } class Logger { public: bool isVerbose () const { return mVerbose; } void setVerbose (bool verbose) { mVerbose = verbose; } void enable (bool status); static void init (const std::shared_ptr &config); static Logger *getInstance () { return mInstance; } private: Logger () = default; static void log (QtMsgType type, const QMessageLogContext &context, const QString &msg); bool mVerbose = false; static QMutex mMutex; static Logger *mInstance; std::shared_ptr mLoggingService; }; #endif // LOGGER_H_ linphone-desktop-4.2.5/linphone-app/src/app/main.cpp000066400000000000000000000027741376717241300224230ustar00rootroot00000000000000/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "AppController.hpp" #include #ifdef QT_QML_DEBUG #include #endif // ============================================================================= int main (int argc, char *argv[]) { AppController controller(argc, argv); #ifdef QT_QML_DEBUG QQmlDebuggingEnabler enabler; #endif //QLoggingCategory::setFilterRules("*.debug=true;qml=false"); App *app = controller.getApp(); if (app->isSecondary()) { qInfo() << QStringLiteral("Running secondary app success. Kill it now."); return EXIT_SUCCESS; } qInfo() << QStringLiteral("Running app..."); int ret; do { app->initContentApp(); ret = app->exec(); } while (ret == App::RestartCode); return ret; } linphone-desktop-4.2.5/linphone-app/src/app/paths/000077500000000000000000000000001376717241300221005ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/src/app/paths/Paths.cpp000066400000000000000000000261511376717241300236700ustar00rootroot00000000000000/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include #include #include #include #include #include "config.h" #include "utils/Utils.hpp" #include "Paths.hpp" // ============================================================================= using namespace std; namespace { constexpr char PathAssistantConfig[] = "/" EXECUTABLE_NAME "/assistant/"; constexpr char PathAvatars[] = "/avatars/"; constexpr char PathCaptures[] = "/" EXECUTABLE_NAME "/captures/"; constexpr char PathCodecs[] = "/codecs/"; constexpr char PathTools[] = "/tools/"; constexpr char PathLogs[] = "/logs/"; //constexpr char PathPlugins[] = "/plugins/"; // Unused constexpr char PathThumbnails[] = "/thumbnails/"; constexpr char PathUserCertificates[] = "/usr-crt/"; constexpr char PathCallHistoryList[] = "/call-history.db"; constexpr char PathConfig[] = "/linphonerc"; constexpr char PathFactoryConfig[] = "/" EXECUTABLE_NAME "/linphonerc-factory"; constexpr char PathRootCa[] = "/" EXECUTABLE_NAME "/rootca.pem"; constexpr char PathFriendsList[] = "/friends.db"; constexpr char PathMessageHistoryList[] = "/message-history.db"; constexpr char PathZrtpSecrets[] = "/zidcache"; } static inline bool dirPathExists (const QString &path) { QDir dir(path); return dir.exists(); } static inline bool filePathExists (const QString &path) { QFileInfo info(path); if (!dirPathExists(info.path())) return false; QFile file(path); return file.exists(); } static inline void ensureDirPathExists (const QString &path) { QDir dir(path); if (!dir.exists() && !dir.mkpath(path)) qFatal("Unable to access at directory: `%s`", Utils::appStringToCoreString(path).c_str()); } static inline void ensureFilePathExists (const QString &path) { QFileInfo info(path); ensureDirPathExists(info.path()); QFile file(path); if (!file.exists() && !file.open(QIODevice::ReadWrite)) qFatal("Unable to access at path: `%s`", Utils::appStringToCoreString(path).c_str()); } static inline string getReadableDirPath (const QString &dirname) { return Utils::appStringToCoreString(QDir::toNativeSeparators(dirname)); } static inline string getWritableDirPath (const QString &dirname) { ensureDirPathExists(dirname); return getReadableDirPath(dirname); } static inline string getReadableFilePath (const QString &filename) { return Utils::appStringToCoreString(QDir::toNativeSeparators(filename)); } static inline string getWritableFilePath (const QString &filename) { ensureFilePathExists(filename); return getReadableFilePath(filename); } // ----------------------------------------------------------------------------- // On Windows or Linux, the folders of the application are : // bin/linphone // lib/ // lib64/ // plugins/ // share/ // But in some cases, it can be : // /linphone // lib/ // lib64/ // share/ // On Mac, we have : // Contents/ // Frameworks/ // MacOs/linphone // Plugins/ // Resources/ // share/ static inline QDir getAppPackageDir () { QDir dir(QCoreApplication::applicationDirPath()); if (dir.dirName() == QLatin1String("MacOS")) { dir.cdUp(); } else if( !dir.exists("lib") && !dir.exists("lib64")){// Check if these folders are in the current path dir.cdUp(); if(!dir.exists("lib") && !dir.exists("lib64") && !dir.exists("plugins")) qWarning() <<"The application's location is not correct: You have to put your 'bin/' folder next to 'lib/' or 'plugins/' folder."; } return dir; } static inline QString getAppPackageDataDirPath() { QDir dir = getAppPackageDir(); #ifdef __APPLE__ if (!dir.cd("Resources")) { dir.mkdir("Resources"); dir.cd("Resources"); } #endif if (!dir.cd("share")) { dir.mkdir("share"); dir.cd("share"); } return dir.absolutePath(); } static inline QString getAppPackageMsPluginsDirPath () { QDir dir = getAppPackageDir(); dir.cd(MSPLUGINS_DIR); return dir.absolutePath(); } static inline QString getAppAssistantConfigDirPath () { return getAppPackageDataDirPath() + PathAssistantConfig; } static inline QString getAppConfigFilePath () { return QStandardPaths::writableLocation(QStandardPaths::AppConfigLocation) + PathConfig; } static inline QString getAppCallHistoryFilePath () { return QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation) + PathCallHistoryList; } static inline QString getAppFactoryConfigFilePath () { return getAppPackageDataDirPath() + PathFactoryConfig; } static inline QString getAppRootCaFilePath () { return getAppPackageDataDirPath() + PathRootCa; } static inline QString getAppFriendsFilePath () { return QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation) + PathFriendsList; } static inline QString getAppMessageHistoryFilePath () { return QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation) + PathMessageHistoryList; } // ----------------------------------------------------------------------------- bool Paths::filePathExists (const string &path) { return filePathExists(Utils::coreStringToAppString(path)); } // ----------------------------------------------------------------------------- string Paths::getAssistantConfigDirPath () { return getReadableDirPath(getAppAssistantConfigDirPath()); } string Paths::getAvatarsDirPath () { return getWritableDirPath(QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation) + PathAvatars); } string Paths::getCallHistoryFilePath () { return getWritableFilePath(getAppCallHistoryFilePath()); } string Paths::getCapturesDirPath () { return getWritableDirPath(QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation) + PathCaptures); } string Paths::getCodecsDirPath () { return getWritableDirPath(QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation) + PathCodecs); } string Paths::getConfigFilePath (const QString &configPath, bool writable) { const QString path = configPath.isEmpty() ? getAppConfigFilePath() : QFileInfo(configPath).absoluteFilePath(); return writable ? getWritableFilePath(path) : getReadableFilePath(path); } string Paths::getFactoryConfigFilePath () { return getReadableFilePath(getAppFactoryConfigFilePath()); } string Paths::getFriendsListFilePath () { return getWritableFilePath(getAppFriendsFilePath()); } string Paths::getDownloadDirPath () { return getWritableDirPath(QStandardPaths::writableLocation(QStandardPaths::DownloadLocation)); } string Paths::getLogsDirPath () { return getWritableDirPath(QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation) + PathLogs); } string Paths::getMessageHistoryFilePath () { return getReadableFilePath(getAppMessageHistoryFilePath());// No need to ensure that the file exists as this DB is deprecated } string Paths::getPackageDataDirPath () { return getReadableDirPath(getAppPackageDataDirPath()); } string Paths::getPackageMsPluginsDirPath () { return getReadableDirPath(getAppPackageMsPluginsDirPath()); } string Paths::getRootCaFilePath () { return getReadableFilePath(getAppRootCaFilePath()); } string Paths::getThumbnailsDirPath () { return getWritableDirPath(QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation) + PathThumbnails); } string Paths::getToolsDirPath () { return getWritableDirPath(QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation) + PathTools); } string Paths::getUserCertificatesDirPath () { return getWritableDirPath(QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation) + PathUserCertificates); } string Paths::getZrtpSecretsFilePath () { return getWritableFilePath(QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation) + PathZrtpSecrets); } // ----------------------------------------------------------------------------- static void migrateFile (const QString &oldPath, const QString &newPath) { QFileInfo info(newPath); ensureDirPathExists(info.path()); if (QFile::copy(oldPath, newPath)) { QFile::remove(oldPath); qInfo() << "Migrated" << oldPath << "to" << newPath; } else { qWarning() << "Failed migration of" << oldPath << "to" << newPath; } } static void migrateConfigurationFile (const QString &oldPath, const QString &newPath) { QFileInfo info(newPath); ensureDirPathExists(info.path()); if (QFile::copy(oldPath, newPath)) { QFile oldFile(oldPath); if (oldFile.open(QIODevice::WriteOnly)) { QTextStream stream(&oldFile); stream << "This file has been migrated to " << newPath; } QFile::setPermissions(oldPath, QFileDevice::ReadOwner); qInfo() << "Migrated" << oldPath << "to" << newPath; } else { qWarning() << "Failed migration of" << oldPath << "to" << newPath; } } void migrateFlatpakVersionFiles(){ #ifdef Q_OS_LINUX if(!filePathExists(QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation) + "/linphone.db")){ // Copy all files if linphone.db doesn't exist QString flatpakPath = QStandardPaths::writableLocation(QStandardPaths::HomeLocation)+"/.var/app/com.belledonnecommunications.linphone/data/linphone"; if( QDir().exists(flatpakPath)){ qInfo() << "Migrating data from Flatpak."; Utils::copyDir(flatpakPath, QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation)); } } #endif } void migrateGTKVersionFiles(){ QString newPath = getAppConfigFilePath(); QString oldBaseDir = QSysInfo::productType() == QLatin1String("windows") ? QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation) : QStandardPaths::writableLocation(QStandardPaths::HomeLocation); QString oldPath = oldBaseDir + "/.linphonerc"; if (!filePathExists(newPath) && filePathExists(oldPath)) migrateConfigurationFile(oldPath, newPath); newPath = getAppCallHistoryFilePath(); oldPath = oldBaseDir + "/.linphone-call-history.db"; if (!filePathExists(newPath) && filePathExists(oldPath)) migrateFile(oldPath, newPath); newPath = getAppFriendsFilePath(); oldPath = oldBaseDir + "/.linphone-friends.db"; if (!filePathExists(newPath) && filePathExists(oldPath)) migrateFile(oldPath, newPath); newPath = getAppMessageHistoryFilePath(); oldPath = oldBaseDir + "/.linphone-history.db"; if (!filePathExists(newPath) && filePathExists(oldPath)) migrateFile(oldPath, newPath); } void Paths::migrate () { migrateFlatpakVersionFiles(); // First, check Flatpak version as it is the earlier version migrateGTKVersionFiles();// Then check old version for migration } linphone-desktop-4.2.5/linphone-app/src/app/paths/Paths.hpp000066400000000000000000000034651376717241300237000ustar00rootroot00000000000000/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef PATHS_H_ #define PATHS_H_ #include // ============================================================================= namespace Paths { bool filePathExists (const std::string &path); std::string getAssistantConfigDirPath (); std::string getAvatarsDirPath (); std::string getCallHistoryFilePath (); std::string getCapturesDirPath (); std::string getCodecsDirPath (); std::string getConfigFilePath (const QString &configPath = QString(), bool writable = true); std::string getDownloadDirPath (); std::string getFactoryConfigFilePath (); std::string getFriendsListFilePath (); std::string getLogsDirPath (); std::string getMessageHistoryFilePath (); std::string getPackageDataDirPath (); std::string getPackageMsPluginsDirPath (); std::string getRootCaFilePath (); std::string getThumbnailsDirPath (); std::string getToolsDirPath (); std::string getUserCertificatesDirPath (); std::string getZrtpDataFilePath (); std::string getZrtpSecretsFilePath (); void migrate (); } #endif // PATHS_H_ linphone-desktop-4.2.5/linphone-app/src/app/providers/000077500000000000000000000000001376717241300227765ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/src/app/providers/AvatarProvider.cpp000066400000000000000000000026011376717241300264320ustar00rootroot00000000000000/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "app/paths/Paths.hpp" #include "utils/Utils.hpp" #include "AvatarProvider.hpp" // ============================================================================= const QString AvatarProvider::ProviderId = "avatar"; AvatarProvider::AvatarProvider () : QQuickImageProvider( QQmlImageProviderBase::Image, QQmlImageProviderBase::ForceAsynchronousImageLoading ) { mAvatarsPath = Utils::coreStringToAppString(Paths::getAvatarsDirPath()); } QImage AvatarProvider::requestImage (const QString &id, QSize *size, const QSize &) { QImage image(mAvatarsPath + id); *size = image.size(); return image; } linphone-desktop-4.2.5/linphone-app/src/app/providers/AvatarProvider.hpp000066400000000000000000000023311376717241300264370ustar00rootroot00000000000000/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef AVATAR_PROVIDER_H_ #define AVATAR_PROVIDER_H_ #include // ============================================================================= class AvatarProvider : public QQuickImageProvider { public: AvatarProvider (); QImage requestImage (const QString &id, QSize *size, const QSize &requestedSize) override; static const QString ProviderId; private: QString mAvatarsPath; }; #endif // AVATAR_PROVIDER_H_ linphone-desktop-4.2.5/linphone-app/src/app/providers/ExternalImageProvider.cpp000066400000000000000000000025661376717241300277530ustar00rootroot00000000000000/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "app/paths/Paths.hpp" #include "utils/Utils.hpp" #include "ExternalImageProvider.hpp" #include // ============================================================================= const QString ExternalImageProvider::ProviderId = "external"; ExternalImageProvider::ExternalImageProvider () : QQuickImageProvider( QQmlImageProviderBase::Image, QQmlImageProviderBase::ForceAsynchronousImageLoading ) { } QImage ExternalImageProvider::requestImage (const QString &id, QSize *size, const QSize &) { QImage image(Utils::getImage(id)); *size = image.size(); return image; } linphone-desktop-4.2.5/linphone-app/src/app/providers/ExternalImageProvider.hpp000066400000000000000000000023351376717241300277520ustar00rootroot00000000000000/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef EXTERNAL_IMAGE_PROVIDER_H_ #define EXTERNAL_IMAGE_PROVIDER_H_ #include // ============================================================================= class ExternalImageProvider : public QQuickImageProvider { public: ExternalImageProvider (); QImage requestImage (const QString &id, QSize *size, const QSize &requestedSize) override; static const QString ProviderId; }; #endif // EXTERNAL_IMAGE_PROVIDER_H_ linphone-desktop-4.2.5/linphone-app/src/app/providers/ImageProvider.cpp000066400000000000000000000230671376717241300262470ustar00rootroot00000000000000/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include #include #include #include #include #include "app/App.hpp" #include "components/other/colors/Colors.hpp" #include "ImageProvider.hpp" // ============================================================================= using namespace std; namespace { // Max image size in bytes. (100Kb) constexpr qint64 MaxImageSize = 102400; } static void removeAttribute (QXmlStreamAttributes &readerAttributes, const QString &name) { auto it = find_if(readerAttributes.cbegin(), readerAttributes.cend(), [&name](const QXmlStreamAttribute &attribute) { return name == attribute.name() && !attribute.prefix().length(); }); if (it != readerAttributes.cend()) readerAttributes.remove(int(distance(readerAttributes.cbegin(), it))); } static QByteArray buildByteArrayAttribute (const QByteArray &name, const QByteArray &value) { QByteArray attribute = name; attribute.append("=\""); attribute.append(value); attribute.append("\" "); return attribute; } static QByteArray parseFillAndStroke (QXmlStreamAttributes &readerAttributes, const Colors &colors) { static QRegExp regex("^color-([^-]+)-(fill|stroke)$"); QByteArray attributes; for (const auto &classValue : readerAttributes.value("class").toLatin1().split(' ')) { regex.indexIn(classValue.trimmed()); if (Q_LIKELY(regex.pos() == -1)) continue; const QStringList list = regex.capturedTexts(); const QVariant colorValue = colors.property(list[1].toStdString().c_str()); if (Q_UNLIKELY(!colorValue.isValid())) { qWarning() << QStringLiteral("Color name `%1` does not exist.").arg(list[1]); continue; } removeAttribute(readerAttributes, list[2]); attributes.append(buildByteArrayAttribute(list[2].toLatin1(), colorValue.value().name().toLatin1())); } return attributes; } static QByteArray parseStyle (QXmlStreamAttributes &readerAttributes, const Colors &colors) { static QRegExp regex("^color-([^-]+)-style-(fill|stroke)$"); QByteArray attribute; QSet overrode; for (const auto &classValue : readerAttributes.value("class").toLatin1().split(' ')) { regex.indexIn(classValue.trimmed()); if (Q_LIKELY(regex.pos() == -1)) continue; const QStringList list = regex.capturedTexts(); overrode.insert(list[2]); const QVariant colorValue = colors.property(list[1].toStdString().c_str()); if (Q_UNLIKELY(!colorValue.isValid())) { qWarning() << QStringLiteral("Color name `%1` does not exist.").arg(list[1]); continue; } attribute.append(list[2].toLatin1()); attribute.append(":"); attribute.append(colorValue.value().name().toLatin1()); attribute.append(";"); } const QByteArrayList styleValues = readerAttributes.value("style").toLatin1().split(';'); for (const auto &styleValue : styleValues) { const QByteArrayList list = styleValue.split(':'); if (Q_UNLIKELY(list.length() > 0 && !overrode.contains(list[0]))) { attribute.append(styleValue); attribute.append(";"); } } removeAttribute(readerAttributes, "style"); if (attribute.length() > 0) { attribute.prepend("style=\""); attribute.append("\" "); } return attribute; } static QByteArray parseAttributes (const QXmlStreamReader &reader, const Colors &colors) { QXmlStreamAttributes readerAttributes = reader.attributes(); QByteArray attributes = parseFillAndStroke(readerAttributes, colors); attributes.append(parseStyle(readerAttributes, colors)); for (const auto &attribute : readerAttributes) { const QByteArray prefix = attribute.prefix().toLatin1(); if (Q_UNLIKELY(prefix.length() > 0)) { attributes.append(prefix); attributes.append(":"); } attributes.append( buildByteArrayAttribute(attribute.name().toLatin1(), attribute.value().toLatin1()) ); } return attributes; } static QByteArray parseDeclarations (const QXmlStreamReader &reader) { QByteArray declarations; for (const auto &declaration : reader.namespaceDeclarations()) { const QByteArray prefix = declaration.prefix().toLatin1(); if (Q_UNLIKELY(prefix.length() > 0)) { declarations.append("xmlns:"); declarations.append(prefix); } else declarations.append("xmlns"); declarations.append("=\""); declarations.append(declaration.namespaceUri().toLatin1()); declarations.append("\" "); } return declarations; } static QByteArray parseStartDocument (const QXmlStreamReader &reader) { QByteArray startDocument = ""); return startDocument; } static QByteArray parseStartElement (const QXmlStreamReader &reader, const Colors &colors) { QByteArray startElement = "<"; startElement.append(reader.name().toLatin1()); startElement.append(" "); startElement.append(parseAttributes(reader, colors)); startElement.append(" "); startElement.append(parseDeclarations(reader)); startElement.append(">"); return startElement; } static QByteArray parseEndElement (const QXmlStreamReader &reader) { QByteArray endElement = ""); return endElement; } // ----------------------------------------------------------------------------- static QByteArray computeContent (QFile &file) { const Colors *colors = App::getInstance()->getColors(); QByteArray content; QXmlStreamReader reader(&file); while (!reader.atEnd()) switch (reader.readNext()) { case QXmlStreamReader::Comment: case QXmlStreamReader::DTD: case QXmlStreamReader::EndDocument: case QXmlStreamReader::Invalid: case QXmlStreamReader::NoToken: case QXmlStreamReader::ProcessingInstruction: break; case QXmlStreamReader::StartDocument: content.append(parseStartDocument(reader)); break; case QXmlStreamReader::StartElement: content.append(parseStartElement(reader, *colors)); break; case QXmlStreamReader::EndElement: content.append(parseEndElement(reader)); break; case QXmlStreamReader::Characters: content.append(reader.text().toLatin1()); break; case QXmlStreamReader::EntityReference: content.append(reader.name().toLatin1()); break; } return reader.hasError() ? QByteArray() : content; } // ----------------------------------------------------------------------------- const QString ImageProvider::ProviderId = "internal"; ImageProvider::ImageProvider () : QQuickImageProvider( QQmlImageProviderBase::Image, QQmlImageProviderBase::ForceAsynchronousImageLoading ) {} // ----------------------------------------------------------------------------- QImage ImageProvider::requestImage (const QString &id, QSize *size, const QSize &requestedSize) { const QString path = QStringLiteral(":%1").arg(id); // qDebug() << QStringLiteral("Image `%1` requested with size: (%2, %3).") // .arg(path).arg(requestedSize.width()).arg(requestedSize.height()); QElapsedTimer timer; timer.start(); // 1. Read and update XML content. *size = QSize(); QFile file(path); if (Q_UNLIKELY(QFileInfo(file).size() > MaxImageSize)) { qWarning() << QStringLiteral("Unable to open large file: `%1`.").arg(path); return QImage(); } if (Q_UNLIKELY(!file.open(QIODevice::ReadOnly))) { qWarning() << QStringLiteral("Unable to open file: `%1`.").arg(path); return QImage(); } const QByteArray content = computeContent(file); if (Q_UNLIKELY(!content.length())) { qWarning() << QStringLiteral("Unable to parse file: `%1`.").arg(path); return QImage(); } // 2. Build svg renderer. QSvgRenderer renderer(content); if (Q_UNLIKELY(!renderer.isValid())) { qWarning() << QStringLiteral("Invalid svg file: `%1`.").arg(path); return QImage(); } QSize askedSize = !requestedSize.isEmpty() ? requestedSize : renderer.defaultSize() * QGuiApplication::primaryScreen()->devicePixelRatio(); // 3. Create image. QImage image(askedSize, QImage::Format_ARGB32_Premultiplied); if (Q_UNLIKELY(image.isNull())) { qWarning() << QStringLiteral("Unable to create image from path: `%1`.") .arg(path); return QImage(); // Memory cannot be allocated. } image.fill(Qt::transparent);// Fill with transparent to set alpha channel *size = image.size(); // 4. Paint! QPainter painter(&image); renderer.render(&painter); // qDebug() << QStringLiteral("Image `%1` loaded in %2 milliseconds.").arg(path).arg(timer.elapsed()); return image; } QPixmap ImageProvider::requestPixmap (const QString &id, QSize *size, const QSize &requestedSize) { return QPixmap::fromImage(requestImage(id, size, requestedSize)); } linphone-desktop-4.2.5/linphone-app/src/app/providers/ImageProvider.hpp000066400000000000000000000024211376717241300262430ustar00rootroot00000000000000/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef IMAGE_PROVIDER_H_ #define IMAGE_PROVIDER_H_ #include // ============================================================================= class ImageProvider : public QQuickImageProvider { public: ImageProvider (); QImage requestImage (const QString &id, QSize *size, const QSize &requestedSize) override; QPixmap requestPixmap (const QString &id, QSize *size, const QSize &requestedSize) override; static const QString ProviderId; }; #endif // IMAGE_PROVIDER_H_ linphone-desktop-4.2.5/linphone-app/src/app/providers/ThumbnailProvider.cpp000066400000000000000000000026341376717241300271450ustar00rootroot00000000000000/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "app/paths/Paths.hpp" #include "utils/Utils.hpp" #include "ThumbnailProvider.hpp" // ============================================================================= const QString ThumbnailProvider::ProviderId = "thumbnail"; ThumbnailProvider::ThumbnailProvider () : QQuickImageProvider( QQmlImageProviderBase::Image, QQmlImageProviderBase::ForceAsynchronousImageLoading ) { mThumbnailsPath = Utils::coreStringToAppString(Paths::getThumbnailsDirPath()); } QImage ThumbnailProvider::requestImage (const QString &id, QSize *size, const QSize &) { QImage image(mThumbnailsPath + id); *size = image.size(); return image; } linphone-desktop-4.2.5/linphone-app/src/app/providers/ThumbnailProvider.hpp000066400000000000000000000023531376717241300271500ustar00rootroot00000000000000/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef THUMBNAIL_PROVIDER_H_ #define THUMBNAIL_PROVIDER_H_ #include // ============================================================================= class ThumbnailProvider : public QQuickImageProvider { public: ThumbnailProvider (); QImage requestImage (const QString &id, QSize *size, const QSize &requestedSize) override; static const QString ProviderId; private: QString mThumbnailsPath; }; #endif // THUMBNAIL_PROVIDER_H_ linphone-desktop-4.2.5/linphone-app/src/app/single-application/000077500000000000000000000000001376717241300245435ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/src/app/single-application/SingleApplication.cpp000066400000000000000000000312071376717241300306570ustar00rootroot00000000000000// The MIT License (MIT) // // Copyright (c) Itay Grudev 2015 - 2016 // // 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. #include #include #include #include #include #include #include #include #include #include #include #include #ifdef Q_OS_UNIX #include #endif // ifdef Q_OS_UNIX #include "utils/Utils.hpp" #include "SingleApplication.hpp" #include "SingleApplicationPrivate.hpp" #ifdef Q_OS_WIN #include #include #endif // ifdef Q_OS_WIN // ============================================================================= using namespace std; namespace { constexpr char NewInstance = 'N'; constexpr char SecondaryInstance = 'S'; constexpr char Reconnect = 'R'; constexpr char InvalidConnection = '\0'; } // ----------------------------------------------------------------------------- SingleApplicationPrivate::SingleApplicationPrivate (SingleApplication *p_ptr) : q_ptr(p_ptr) { server = nullptr; socket = nullptr; } SingleApplicationPrivate::~SingleApplicationPrivate () { if (socket != nullptr) { socket->close(); delete socket; } memory->lock(); InstancesInfo *inst = static_cast(memory->data()); if (server != nullptr) { server->close(); delete server; inst->primary = false; } memory->unlock(); delete memory; } void SingleApplicationPrivate::genBlockServerName (int timeout) { QCryptographicHash appData(QCryptographicHash::Sha256); appData.addData("SingleApplication", 17); appData.addData(QApplication::applicationName().toUtf8()); appData.addData(QApplication::organizationName().toUtf8()); appData.addData(QApplication::organizationDomain().toUtf8()); if (!(options & SingleApplication::Mode::ExcludeAppVersion)) { appData.addData(QApplication::applicationVersion().toUtf8()); } if (!(options & SingleApplication::Mode::ExcludeAppPath)) { #ifdef Q_OS_WIN appData.addData(QApplication::applicationFilePath().toLower().toUtf8()); #else appData.addData(QApplication::applicationFilePath().toUtf8()); #endif // ifdef Q_OS_WIN } // User level block requires a user specific data in the hash if (options & SingleApplication::Mode::User) { #ifdef Q_OS_WIN Q_UNUSED(timeout) wchar_t username[UNLEN + 1]; // Specifies size of the buffer on input DWORD usernameLength = UNLEN + 1; if (GetUserNameW(username, &usernameLength)) { appData.addData(QString::fromWCharArray(username).toUtf8()); } else { appData.addData(QStandardPaths::standardLocations(QStandardPaths::HomeLocation).join("").toUtf8()); } #endif // ifdef Q_OS_WIN #ifdef Q_OS_UNIX QProcess process; process.start("whoami"); if (process.waitForFinished(timeout) && process.exitCode() == QProcess::NormalExit) { appData.addData(process.readLine()); } else { appData.addData( QDir( QStandardPaths::standardLocations(QStandardPaths::HomeLocation).first() ).absolutePath().toUtf8() ); } #endif // ifdef Q_OS_UNIX } // Replace the backslash in RFC 2045 Base64 [a-zA-Z0-9+/=] to comply with // server naming requirements. blockServerName = appData.result().toBase64().replace("/", "_"); } void SingleApplicationPrivate::startPrimary (bool resetMemory) { #ifdef Q_OS_UNIX signal(SIGINT, SingleApplicationPrivate::terminate); #endif // ifdef Q_OS_UNIX // Successful creation means that no main process exists // So we start a QLocalServer to listen for connections QLocalServer::removeServer(blockServerName); server = new QLocalServer(); // Restrict access to the socket according to the // SingleApplication::Mode::User flag on User level or no restrictions if (options & SingleApplication::Mode::User) { server->setSocketOptions(QLocalServer::UserAccessOption); } else { server->setSocketOptions(QLocalServer::WorldAccessOption); } server->listen(blockServerName); QObject::connect( server, &QLocalServer::newConnection, this, &SingleApplicationPrivate::slotConnectionEstablished ); // Reset the number of connections memory->lock(); InstancesInfo *inst = static_cast(memory->data()); if (resetMemory) { inst->primary = true; inst->secondary = 0; inst->primaryId = q_ptr->applicationPid(); } else { inst->primary = true; inst->primaryId = q_ptr->applicationPid(); } memory->unlock(); instanceNumber = 0; } void SingleApplicationPrivate::startSecondary () { #ifdef Q_OS_UNIX signal(SIGINT, SingleApplicationPrivate::terminate); #endif // ifdef Q_OS_UNIX } void SingleApplicationPrivate::connectToPrimary (int msecs, char connectionType) { // Connect to the Local Server of the Primary Instance if not already // connected. if (socket == nullptr) { socket = new QLocalSocket(); } // If already connected - we are done; if (socket->state() == QLocalSocket::ConnectedState) return; // If not connect if (socket->state() == QLocalSocket::UnconnectedState || socket->state() == QLocalSocket::ClosingState) { socket->connectToServer(blockServerName); } // Wait for being connected if (socket->state() == QLocalSocket::ConnectingState) { socket->waitForConnected(msecs); } // Initialisation message according to the SingleApplication protocol if (socket->state() == QLocalSocket::ConnectedState) { // Notify the parent that a new instance had been started; QByteArray initMsg = blockServerName.toLatin1(); initMsg.append(connectionType); initMsg.append(reinterpret_cast(&instanceNumber), sizeof(quint32)); initMsg.append(QByteArray::number(qChecksum(initMsg.constData(), uint(initMsg.length())), 256)); socket->write(initMsg); socket->flush(); socket->waitForBytesWritten(msecs); } } #ifdef Q_OS_UNIX void SingleApplicationPrivate::terminate (int signum) { Q_UNUSED(signum); SingleApplication::instance()->quit(); } #endif // ifdef Q_OS_UNIX /** * @brief Executed when a connection has been made to the LocalServer */ void SingleApplicationPrivate::slotConnectionEstablished () { Q_Q(SingleApplication); QLocalSocket *nextConnSocket = server->nextPendingConnection(); // Verify that the new connection follows the SingleApplication protocol char connectionType = InvalidConnection; quint32 instanceId; QByteArray initMsg, tmp; if (nextConnSocket->waitForReadyRead(100)) { tmp = nextConnSocket->read(blockServerName.length()); // Verify that the socket data start with blockServerName if (tmp == blockServerName.toLatin1()) { initMsg = tmp; connectionType = nextConnSocket->read(1)[0]; switch (connectionType) { case NewInstance: case SecondaryInstance: case Reconnect: { initMsg += connectionType; tmp = nextConnSocket->read(sizeof(quint32)); const char *data = tmp.constData(); instanceId = quint32(*data); initMsg += tmp; // Verify the checksum of the initMsg QByteArray checksum = QByteArray::number( qChecksum(initMsg.constData(), uint(initMsg.length())), 256 ); tmp = nextConnSocket->read(checksum.length()); if (checksum == tmp) break; // Otherwise set to invalid connection (next line) connectionType = InvalidConnection; break; } default: connectionType = InvalidConnection; } } } if (connectionType == InvalidConnection) { nextConnSocket->close(); delete nextConnSocket; return; } QObject::connect(nextConnSocket, &QLocalSocket::aboutToClose, this, [nextConnSocket, instanceId, this]() { emit this->slotClientConnectionClosed(nextConnSocket, instanceId); }); QObject::connect(nextConnSocket, &QLocalSocket::readyRead, this, [nextConnSocket, instanceId, this]() { emit this->slotDataAvailable(nextConnSocket, instanceId); }); if (connectionType == NewInstance || ( connectionType == SecondaryInstance && options & SingleApplication::Mode::SecondaryNotification ) ) { emit q->instanceStarted(); } if (nextConnSocket->bytesAvailable() > 0) { emit this->slotDataAvailable(nextConnSocket, instanceId); } } void SingleApplicationPrivate::slotDataAvailable (QLocalSocket *dataSocket, quint32 instanceId) { Q_Q(SingleApplication); emit q->receivedMessage(instanceId, dataSocket->readAll()); } void SingleApplicationPrivate::slotClientConnectionClosed (QLocalSocket *closedSocket, quint32 instanceId) { if (closedSocket->bytesAvailable() > 0) emit slotDataAvailable(closedSocket, instanceId); closedSocket->deleteLater(); } /** * @brief Constructor. Checks and fires up LocalServer or closes the program * if another instance already exists * @param argc * @param argv * @param {bool} allowSecondaryInstances */ SingleApplication::SingleApplication (int &argc, char *argv[], bool allowSecondary, Options options, int timeout) : QApplication(argc, argv), d_ptr(new SingleApplicationPrivate(this)) { Q_D(SingleApplication); // Store the current mode of the program d->options = options; // Generating an application ID used for identifying the shared memory // block and QLocalServer d->genBlockServerName(timeout); // Guarantee thread safe behaviour with a shared memory block. Also by // explicitly attaching it and then deleting it we make sure that the // memory is deleted even if the process had crashed on Unix. #ifdef Q_OS_UNIX d->memory = new QSharedMemory(d->blockServerName); d->memory->attach(); delete d->memory; #endif // ifdef Q_OS_UNIX d->memory = new QSharedMemory(d->blockServerName); // Create a shared memory block if (d->memory->create(sizeof(InstancesInfo))) { d->startPrimary(true); return; } // Attempt to attach to the memory segment if (d->memory->attach()) { d->memory->lock(); InstancesInfo *inst = static_cast(d->memory->data()); if (!inst->primary || !Utils::processExists(inst->primaryId)) { // Check if there is not a primary instance and if there is, is it still running? d->startPrimary(false); d->memory->unlock(); return; } // Check if another instance can be started if (allowSecondary) { inst->secondary += 1; d->instanceNumber = inst->secondary; d->startSecondary(); if (d->options & Mode::SecondaryNotification) d->connectToPrimary(timeout, SecondaryInstance); d->memory->unlock(); return; } d->memory->unlock(); } d->connectToPrimary(timeout, NewInstance); delete d; ::exit(EXIT_SUCCESS); } /** * @brief Destructor */ SingleApplication::~SingleApplication () { Q_D(SingleApplication); delete d; } bool SingleApplication::isPrimary () { Q_D(SingleApplication); return d->server != nullptr; } bool SingleApplication::isSecondary () { Q_D(SingleApplication); return d->server == nullptr; } quint32 SingleApplication::instanceId () { Q_D(SingleApplication); return d->instanceNumber; } bool SingleApplication::sendMessage (QByteArray message, int timeout) { Q_D(SingleApplication); // Nobody to connect to if (isPrimary()) return false; // Make sure the socket is connected d->connectToPrimary(timeout, Reconnect); d->socket->write(message); bool dataWritten = d->socket->flush(); d->socket->waitForBytesWritten(timeout); return dataWritten; } void SingleApplication::quit () { QCoreApplication::quit(); } linphone-desktop-4.2.5/linphone-app/src/app/single-application/SingleApplication.hpp000066400000000000000000000106121376717241300306610ustar00rootroot00000000000000// The MIT License (MIT) // // Copyright (c) Itay Grudev 2015 - 2016 // // 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. // See: https://github.com/itay-grudev/SingleApplication/ #ifndef SINGLE_APPLICATION_H_ #define SINGLE_APPLICATION_H_ #include #include #include // ============================================================================= class SingleApplicationPrivate; /** * @brief The SingleApplication class handles multipe instances of the same * Application * @see QCoreApplication */ class SingleApplication : public QApplication { Q_OBJECT; public: /** * @brief Mode of operation of SingleApplication. * Whether the block should be user-wide or system-wide and whether the * primary instance should be notified when a secondary instance had been * started. * @note Operating system can restrict the shared memory blocks to the same * user, in which case the User/System modes will have no effect and the * block will be user wide. * @enum */ enum Mode { User = 1 << 0, System = 1 << 1, SecondaryNotification = 1 << 2, ExcludeAppVersion = 1 << 3, ExcludeAppPath = 1 << 4 }; Q_DECLARE_FLAGS(Options, Mode) /** * @brief Intitializes a SingleApplication instance with argc command line * arguments in argv * @arg {int &} argc - Number of arguments in argv * @arg {const char *[]} argv - Supplied command line arguments * @arg {bool} allowSecondary - Whether to start the instance as secondary * if there is already a primary instance. * @arg {Mode} mode - Whether for the SingleApplication block to be applied * User wide or System wide. * @arg {int} timeout - Timeout to wait in milliseconds. * @note argc and argv may be changed as Qt removes arguments that it * recognizes * @note Mode::SecondaryNotification only works if set on both the primary * instance and the secondary instance. * @note The timeout is just a hint for the maximum time of blocking * operations. It does not guarantee that the SingleApplication * initialisation will be completed in given time, though is a good hint. * Usually 4*timeout would be the worst case (fail) scenario. * @see See the corresponding QAPPLICATION_CLASS constructor for reference */ explicit SingleApplication (int &argc, char *argv[], bool allowSecondary = false, Options options = Mode::User, int timeout = 100); virtual ~SingleApplication (); /** * @brief Returns if the instance is the primary instance * @returns {bool} */ bool isPrimary (); /** * @brief Returns if the instance is a secondary instance * @returns {bool} */ bool isSecondary (); /** * @brief Returns a unique identifier for the current instance * @returns {int} */ quint32 instanceId (); /** * @brief Sends a message to the primary instance. Returns true on success. * @param {int} timeout - Timeout for connecting * @returns {bool} * @note sendMessage() will return false if invoked from the primary * instance. */ bool sendMessage (QByteArray message, int timeout = 100); virtual void quit (); signals: void instanceStarted (); void receivedMessage (quint32 instanceId, QByteArray message); private: SingleApplicationPrivate *d_ptr; Q_DECLARE_PRIVATE(SingleApplication) }; Q_DECLARE_OPERATORS_FOR_FLAGS(SingleApplication::Options) #endif // SINGLE_APPLICATION_H_ linphone-desktop-4.2.5/linphone-app/src/app/single-application/SingleApplicationDBus.cpp000066400000000000000000000070241376717241300314350ustar00rootroot00000000000000/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include #include #include "config.h" #include "SingleApplication.hpp" #include "SingleApplicationDBusPrivate.hpp" // ============================================================================= namespace { constexpr char ServiceName[] = "org." EXECUTABLE_NAME ".SingleApplication"; } SingleApplicationPrivate::SingleApplicationPrivate (SingleApplication *q_ptr) : QDBusAbstractAdaptor(q_ptr), q_ptr(q_ptr) {} QDBusConnection SingleApplicationPrivate::getBus () const { if (options & SingleApplication::Mode::User) return QDBusConnection::sessionBus(); return QDBusConnection::systemBus(); } void SingleApplicationPrivate::startPrimary () { signal(SIGINT, SingleApplicationPrivate::terminate); if (!getBus().registerObject("/", this, QDBusConnection::ExportAllSlots)) qWarning() << QStringLiteral("Failed to register single application object on DBus."); instanceNumber = 0; } void SingleApplicationPrivate::startSecondary () { signal(SIGINT, SingleApplicationPrivate::terminate); instanceNumber = 1; } void SingleApplicationPrivate::terminate (int signum) { Q_UNUSED(signum) SingleApplication::instance()->quit(); } SingleApplication::SingleApplication (int &argc, char *argv[], bool allowSecondary, Options options, int) : QApplication(argc, argv), d_ptr(new SingleApplicationPrivate(this)) { Q_D(SingleApplication); // Store the current mode of the program. d->options = options; if (!d->getBus().isConnected()) { qWarning() << QStringLiteral("Cannot connect to the D-Bus session bus."); delete d; ::exit(EXIT_FAILURE); } if (d->getBus().registerService(ServiceName)) { d->startPrimary(); return; } if (allowSecondary) { d->startSecondary(); return; } delete d; ::exit(EXIT_SUCCESS); } SingleApplication::~SingleApplication () { Q_D(SingleApplication); delete d; } bool SingleApplication::isPrimary () { Q_D(SingleApplication); return d->instanceNumber == 0; } bool SingleApplication::isSecondary () { Q_D(SingleApplication); return d->instanceNumber != 0; } quint32 SingleApplication::instanceId () { Q_D(SingleApplication); return d->instanceNumber; } bool SingleApplication::sendMessage (QByteArray message, int timeout) { Q_D(SingleApplication); if (isPrimary()) return false; QDBusInterface iface(ServiceName, "/", "", d->getBus()); if (iface.isValid()) { iface.setTimeout(timeout); iface.call(QDBus::Block, "handleMessageReceived", instanceId(), message); return true; } return false; } void SingleApplicationPrivate::handleMessageReceived (quint32 instanceId, QByteArray message) { Q_Q(SingleApplication); emit q->receivedMessage(instanceId, message); } void SingleApplication::quit () { QCoreApplication::quit(); } linphone-desktop-4.2.5/linphone-app/src/app/single-application/SingleApplicationDBusPrivate.hpp000066400000000000000000000034341376717241300327760ustar00rootroot00000000000000/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef SINGLE_APPLICATION_DBUS_PRIVATE_H_ #define SINGLE_APPLICATION_DBUS_PRIVATE_H_ #include #include #include "SingleApplication.hpp" // ============================================================================= struct InstancesInfo { bool primary; quint32 secondary; }; class SingleApplicationPrivate : public QDBusAbstractAdaptor { Q_OBJECT; Q_CLASSINFO("D-Bus Interface", "org.linphone.DBus.SingleApplication"); public: SingleApplicationPrivate (SingleApplication *q_ptr); QDBusConnection getBus () const; void startPrimary (); void startSecondary (); static void terminate (int signum); SingleApplication *q_ptr; SingleApplication::Options options; quint32 instanceNumber; // Explicit public slot. Cannot be private, must be exported as a method via D-Bus. public slots: void handleMessageReceived (quint32 instanceId, QByteArray message); private: Q_DECLARE_PUBLIC(SingleApplication); }; #endif // SINGLE_APPLICATION_DBUS_PRIVATE_H_ linphone-desktop-4.2.5/linphone-app/src/app/single-application/SingleApplicationPrivate.hpp000066400000000000000000000065621376717241300322250ustar00rootroot00000000000000/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ // The MIT License (MIT) // // Copyright (c) Itay Grudev 2015 - 2016 // // 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. // // W A R N I N G !!! // ----------------- // // This file is not part of the SingleApplication API. It is used purely as an // implementation detail. This header file may change from version to // version without notice, or may even be removed. // #ifndef SINGLE_APPLICATION_PRIVATE_H_ #define SINGLE_APPLICATION_PRIVATE_H_ #include #include #include #include #include "SingleApplication.hpp" // ============================================================================= struct InstancesInfo { bool primary; quint32 secondary; qint64 primaryId; }; class SingleApplicationPrivate : public QObject { Q_OBJECT public: Q_DECLARE_PUBLIC(SingleApplication) SingleApplicationPrivate (SingleApplication *q_ptr); ~SingleApplicationPrivate (); void genBlockServerName (int msecs); void startPrimary (bool resetMemory); void startSecondary (); void connectToPrimary (int msecs, char connectionType); #ifdef Q_OS_UNIX static void terminate (int signum); #endif // ifdef Q_OS_UNIX QSharedMemory *memory; SingleApplication *q_ptr; QLocalSocket *socket; QLocalServer *server; quint32 instanceNumber; QString blockServerName; SingleApplication::Options options; public Q_SLOTS: void slotConnectionEstablished (); void slotDataAvailable (QLocalSocket *, quint32); void slotClientConnectionClosed (QLocalSocket *, quint32); }; #endif // SINGLE_APPLICATION_PRIVATE_H_ linphone-desktop-4.2.5/linphone-app/src/app/translator/000077500000000000000000000000001376717241300231525ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/src/app/translator/DefaultTranslator.cpp000066400000000000000000000042561376717241300273230ustar00rootroot00000000000000/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include #include #include "DefaultTranslator.hpp" // ============================================================================= DefaultTranslator::DefaultTranslator (QObject *parent) : QTranslator(parent) { QDirIterator it(":", QDirIterator::Subdirectories); while (it.hasNext()) { QFileInfo info(it.next()); if (info.suffix() == QLatin1String("qml")) { QString dir = info.absoluteDir().absolutePath(); // Ignore extra selectors. // TODO: Remove 5.9 support in July 2019. for (const auto &selector : { "+linux", "+mac", "+windows", "+custom", "+5.9" }) if (dir.contains(selector)) goto end; // Ignore default imports. if (dir.startsWith(":/QtQuick")) continue; QString basename = info.baseName(); if (!mContexts.contains(basename)) mContexts << basename; } end:; } } QString DefaultTranslator::translate ( const char *context, const char *sourceText, const char *disambiguation, int n ) const { if (!context) return QString(""); QString translation = QTranslator::translate(context, sourceText, disambiguation, n); if (translation.length() == 0 && mContexts.contains(context)) qWarning() << QStringLiteral("Unable to find a translation. (context=%1, label=%2, disambiguation=%3)") .arg(context).arg(sourceText).arg(disambiguation); return translation; } linphone-desktop-4.2.5/linphone-app/src/app/translator/DefaultTranslator.hpp000066400000000000000000000024371376717241300273270ustar00rootroot00000000000000/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef DEFAULT_TRANSLATOR_H_ #define DEFAULT_TRANSLATOR_H_ #include #include // ============================================================================= class DefaultTranslator : public QTranslator { public: DefaultTranslator (QObject *parent = Q_NULLPTR); QString translate ( const char *context, const char *sourceText, const char *disambiguation = Q_NULLPTR, int n = -1 ) const override; private: QSet mContexts; }; #endif // DEFAULT_TRANSLATOR_H_ linphone-desktop-4.2.5/linphone-app/src/components/000077500000000000000000000000001376717241300223665ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/src/components/Components.hpp000066400000000000000000000043731376717241300252330ustar00rootroot00000000000000/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef COMPONENTS_H_ #define COMPONENTS_H_ #include "assistant/AssistantModel.hpp" #include "authentication/AuthenticationNotifier.hpp" #include "call/CallModel.hpp" #include "calls/CallsListModel.hpp" #include "calls/CallsListProxyModel.hpp" #include "camera/Camera.hpp" #include "camera/CameraPreview.hpp" #include "chat/ChatProxyModel.hpp" #include "codecs/AudioCodecsModel.hpp" #include "codecs/VideoCodecsModel.hpp" #include "conference/ConferenceAddModel.hpp" #include "conference/ConferenceModel.hpp" #include "contact/ContactModel.hpp" #include "contact/VcardModel.hpp" #include "contacts/ContactsListModel.hpp" #include "contacts/ContactsListProxyModel.hpp" #include "core/CoreHandlers.hpp" #include "core/CoreManager.hpp" #include "file/FileDownloader.hpp" #include "file/FileExtractor.hpp" #include "history/HistoryProxyModel.hpp" #include "notifier/Notifier.hpp" #include "presence/OwnPresenceModel.hpp" #include "settings/AccountSettingsModel.hpp" #include "settings/SettingsModel.hpp" #include "sip-addresses/SipAddressesModel.hpp" #include "sip-addresses/SipAddressesProxyModel.hpp" #include "sound-player/SoundPlayer.hpp" #include "telephone-numbers/TelephoneNumbersModel.hpp" #include "timeline/TimelineModel.hpp" #include "url-handlers/UrlHandlers.hpp" #include "other/colors/Colors.hpp" #include "other/clipboard/Clipboard.hpp" #include "other/desktop-tools/DesktopTools.hpp" #include "other/text-to-speech/TextToSpeech.hpp" #include "other/units/Units.hpp" #endif // COMPONENTS_H_ linphone-desktop-4.2.5/linphone-app/src/components/assistant/000077500000000000000000000000001376717241300243775ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/src/components/assistant/AssistantModel.cpp000066400000000000000000000372461376717241300300510ustar00rootroot00000000000000/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "app/paths/Paths.hpp" #include "components/core/CoreManager.hpp" #include "components/settings/AccountSettingsModel.hpp" #include "components/settings/SettingsModel.hpp" #include "components/sip-addresses/SipAddressesModel.hpp" #include "utils/LinphoneUtils.hpp" #include "utils/Utils.hpp" #include "AssistantModel.hpp" #include // ============================================================================= using namespace std; namespace { constexpr char DefaultXmlrpcUri[] = "https://subscribe.linphone.org:444/wizard.php"; } class AssistantModel::Handlers : public linphone::AccountCreatorListener { public: Handlers (AssistantModel *assistant) { mAssistant = assistant; } private: void createProxyConfig (const shared_ptr &creator) { shared_ptr proxyConfig = creator->createProxyConfig(); Q_CHECK_PTR(proxyConfig); CoreManager::getInstance()->getSettingsModel()->configureRlsUri(proxyConfig); } void onCreateAccount ( const shared_ptr &, linphone::AccountCreator::Status status, const string & ) override { if (status == linphone::AccountCreator::Status::AccountCreated){ emit mAssistant->createStatusChanged(QString("")); }else { if (status == linphone::AccountCreator::Status::RequestFailed) emit mAssistant->createStatusChanged(tr("requestFailed")); else if (status == linphone::AccountCreator::Status::ServerError) emit mAssistant->createStatusChanged(tr("cannotSendSms")); else emit mAssistant->createStatusChanged(tr("accountAlreadyExists")); } } void onIsAccountExist ( const shared_ptr &creator, linphone::AccountCreator::Status status, const string & ) override { if (status == linphone::AccountCreator::Status::AccountExist || status == linphone::AccountCreator::Status::AccountExistWithAlias) { createProxyConfig(creator); CoreManager::getInstance()->getSipAddressesModel()->reset(); emit mAssistant->loginStatusChanged(QString("")); } else { if (status == linphone::AccountCreator::Status::RequestFailed) emit mAssistant->loginStatusChanged(tr("requestFailed")); else emit mAssistant->loginStatusChanged(tr("loginWithUsernameFailed")); } } void onActivateAccount ( const shared_ptr &creator, linphone::AccountCreator::Status status, const string & ) override { if ( status == linphone::AccountCreator::Status::AccountActivated || status == linphone::AccountCreator::Status::AccountAlreadyActivated ) { if (creator->getEmail().empty()) createProxyConfig(creator); CoreManager::getInstance()->getSipAddressesModel()->reset(); emit mAssistant->activateStatusChanged(QString("")); } else { if (status == linphone::AccountCreator::Status::RequestFailed) emit mAssistant->activateStatusChanged(tr("requestFailed")); else emit mAssistant->activateStatusChanged(tr("smsActivationFailed")); } } void onIsAccountActivated ( const shared_ptr &creator, linphone::AccountCreator::Status status, const string & ) override { if (status == linphone::AccountCreator::Status::AccountActivated) { createProxyConfig(creator); CoreManager::getInstance()->getSipAddressesModel()->reset(); emit mAssistant->activateStatusChanged(QString("")); } else { if (status == linphone::AccountCreator::Status::RequestFailed) emit mAssistant->activateStatusChanged(tr("requestFailed")); else emit mAssistant->activateStatusChanged(tr("emailActivationFailed")); } } void onRecoverAccount ( const shared_ptr &, linphone::AccountCreator::Status status, const string & ) override { if (status == linphone::AccountCreator::Status::RequestOk) { CoreManager::getInstance()->getSipAddressesModel()->reset(); emit mAssistant->recoverStatusChanged(QString("")); } else { if (status == linphone::AccountCreator::Status::RequestFailed) emit mAssistant->recoverStatusChanged(tr("requestFailed")); else if (status == linphone::AccountCreator::Status::ServerError) emit mAssistant->recoverStatusChanged(tr("cannotSendSms")); else emit mAssistant->recoverStatusChanged(tr("loginWithPhoneNumberFailed")); } } private: AssistantModel *mAssistant; }; // ----------------------------------------------------------------------------- AssistantModel::AssistantModel (QObject *parent) : QObject(parent) { mHandlers = make_shared(this); shared_ptr core = CoreManager::getInstance()->getCore(); mAccountCreator = core->createAccountCreator( core->getConfig()->getString("assistant", "xmlrpc_url", DefaultXmlrpcUri) ); mAccountCreator->addListener(mHandlers); } // ----------------------------------------------------------------------------- void AssistantModel::activate () { if (mAccountCreator->getEmail().empty()) mAccountCreator->activateAccount(); else mAccountCreator->isAccountActivated(); } void AssistantModel::create () { mAccountCreator->createAccount(); } void AssistantModel::login () { if (!mCountryCode.isEmpty()) { mAccountCreator->recoverAccount(); return; } shared_ptr config(CoreManager::getInstance()->getCore()->getConfig()); if (!config->getString("assistant", "xmlrpc_url", "").empty()) { mAccountCreator->isAccountExist(); return; } // No verification if no xmlrpc url. Use addOtherSipAccount directly. QVariantMap map; map["sipDomain"] = Utils::coreStringToAppString(config->getString("assistant", "domain", "")); map["username"] = getUsername(); map["password"] = getPassword(); emit loginStatusChanged(addOtherSipAccount(map) ? QString("") : tr("unableToAddAccount")); } void AssistantModel::reset () { mCountryCode = QString(""); mAccountCreator->reset(); emit emailChanged(QString(""), QString("")); emit passwordChanged(QString(""), QString("")); emit phoneNumberChanged(QString(""), QString("")); emit usernameChanged(QString(""), QString("")); } // ----------------------------------------------------------------------------- bool AssistantModel::addOtherSipAccount (const QVariantMap &map) { CoreManager *coreManager = CoreManager::getInstance(); shared_ptr factory = linphone::Factory::get(); shared_ptr core = coreManager->getCore(); shared_ptr proxyConfig = core->createProxyConfig(); const QString domain = map["sipDomain"].toString(); QString sipAddress = QStringLiteral("sip:%1@%2") .arg(map["username"].toString()).arg(domain); // Server address. { shared_ptr address = factory->createAddress( Utils::appStringToCoreString(QStringLiteral("sip:%1").arg(domain)) ); const QString &transport(map["transport"].toString()); if (!transport.isEmpty()) address->setTransport(LinphoneUtils::stringToTransportType(transport)); if (proxyConfig->setServerAddr(address->asString())) { qWarning() << QStringLiteral("Unable to add server address: `%1`.") .arg(Utils::coreStringToAppString(address->asString())); return false; } } // Sip Address. shared_ptr address = factory->createAddress(Utils::appStringToCoreString(sipAddress)); if (!address) { qWarning() << QStringLiteral("Unable to create sip address object from: `%1`.").arg(sipAddress); return false; } address->setDisplayName(Utils::appStringToCoreString(map["displayName"].toString())); proxyConfig->setIdentityAddress(address); // AuthInfo. core->addAuthInfo( factory->createAuthInfo( address->getUsername(), // Username. "", // User ID. Utils::appStringToCoreString(map["password"].toString()), // Password. "", // HA1. "", // Realm. address->getDomain() // Domain. ) ); AccountSettingsModel *accountSettingsModel = coreManager->getAccountSettingsModel(); if (accountSettingsModel->addOrUpdateProxyConfig(proxyConfig)) { accountSettingsModel->setDefaultProxyConfig(proxyConfig); return true; } return false; } // ----------------------------------------------------------------------------- QString AssistantModel::getEmail () const { return Utils::coreStringToAppString(mAccountCreator->getEmail()); } void AssistantModel::setEmail (const QString &email) { shared_ptr config = CoreManager::getInstance()->getCore()->getConfig(); QString error; switch (mAccountCreator->setEmail(Utils::appStringToCoreString(email))) { case linphone::AccountCreator::EmailStatus::Ok: break; case linphone::AccountCreator::EmailStatus::Malformed: error = tr("emailStatusMalformed"); break; case linphone::AccountCreator::EmailStatus::InvalidCharacters: error = tr("emailStatusMalformedInvalidCharacters"); break; } emit emailChanged(email, error); } // ----------------------------------------------------------------------------- QString AssistantModel::getPassword () const { return Utils::coreStringToAppString(mAccountCreator->getPassword()); } void AssistantModel::setPassword (const QString &password) { shared_ptr config = CoreManager::getInstance()->getCore()->getConfig(); QString error; switch (mAccountCreator->setPassword(Utils::appStringToCoreString(password))) { case linphone::AccountCreator::PasswordStatus::Ok: break; case linphone::AccountCreator::PasswordStatus::TooShort: error = tr("passwordStatusTooShort").arg(config->getInt("assistant", "password_min_length", 1)); break; case linphone::AccountCreator::PasswordStatus::TooLong: error = tr("passwordStatusTooLong").arg(config->getInt("assistant", "password_max_length", -1)); break; case linphone::AccountCreator::PasswordStatus::InvalidCharacters: error = tr("passwordStatusInvalidCharacters") .arg(Utils::coreStringToAppString(config->getString("assistant", "password_regex", ""))); break; case linphone::AccountCreator::PasswordStatus::MissingCharacters: error = tr("passwordStatusMissingCharacters") .arg(Utils::coreStringToAppString(config->getString("assistant", "missing_characters", ""))); break; } emit passwordChanged(password, error); } // ----------------------------------------------------------------------------- QString AssistantModel::getCountryCode () const { return mCountryCode; } void AssistantModel::setCountryCode (const QString &countryCode) { mCountryCode = countryCode; emit countryCodeChanged(countryCode); } // ----------------------------------------------------------------------------- QString AssistantModel::getPhoneNumber () const { return Utils::coreStringToAppString(mAccountCreator->getPhoneNumber()); } void AssistantModel::setPhoneNumber (const QString &phoneNumber) { shared_ptr config = CoreManager::getInstance()->getCore()->getConfig(); QString error; switch (static_cast( mAccountCreator->setPhoneNumber(Utils::appStringToCoreString(phoneNumber), Utils::appStringToCoreString(mCountryCode)) )) { case linphone::AccountCreator::PhoneNumberStatus::Ok: break; case linphone::AccountCreator::PhoneNumberStatus::Invalid: error = tr("phoneNumberStatusInvalid"); break; case linphone::AccountCreator::PhoneNumberStatus::TooShort: error = tr("phoneNumberStatusTooShort"); break; case linphone::AccountCreator::PhoneNumberStatus::TooLong: error = tr("phoneNumberStatusTooLong"); break; case linphone::AccountCreator::PhoneNumberStatus::InvalidCountryCode: error = tr("phoneNumberStatusInvalidCountryCode"); break; default: break; } emit phoneNumberChanged(phoneNumber, error); } // ----------------------------------------------------------------------------- QString AssistantModel::getUsername () const { return QString::fromStdString(mAccountCreator->getUsername()); } void AssistantModel::setUsername (const QString &username) { emit usernameChanged( username, mapAccountCreatorUsernameStatusToString( mAccountCreator->setUsername(Utils::appStringToCoreString(username)) ) ); } // ----------------------------------------------------------------------------- QString AssistantModel::getDisplayName () const { return Utils::coreStringToAppString(mAccountCreator->getDisplayName()); } void AssistantModel::setDisplayName (const QString &displayName) { emit displayNameChanged( displayName, mapAccountCreatorUsernameStatusToString( mAccountCreator->setDisplayName(Utils::appStringToCoreString(displayName)) ) ); } // ----------------------------------------------------------------------------- QString AssistantModel::getActivationCode () const { return Utils::coreStringToAppString(mAccountCreator->getActivationCode()); } void AssistantModel::setActivationCode (const QString &activationCode) { mAccountCreator->setActivationCode(Utils::appStringToCoreString(activationCode)); emit activationCodeChanged(activationCode); } // ----------------------------------------------------------------------------- QString AssistantModel::getConfigFilename () const { return mConfigFilename; } void AssistantModel::setConfigFilename (const QString &configFilename) { mConfigFilename = configFilename; QString configPath = Utils::coreStringToAppString(Paths::getAssistantConfigDirPath()) + configFilename; qInfo() << QStringLiteral("Set config on assistant: `%1`.").arg(configPath); CoreManager::getInstance()->getCore()->getConfig()->loadFromXmlFile( Utils::appStringToCoreString(configPath) ); emit configFilenameChanged(configFilename); } // ----------------------------------------------------------------------------- QString AssistantModel::mapAccountCreatorUsernameStatusToString (linphone::AccountCreator::UsernameStatus status) const { shared_ptr config = CoreManager::getInstance()->getCore()->getConfig(); QString error; switch (status) { case linphone::AccountCreator::UsernameStatus::Ok: break; case linphone::AccountCreator::UsernameStatus::TooShort: error = tr("usernameStatusTooShort").arg(config->getInt("assistant", "username_min_length", 1)); break; case linphone::AccountCreator::UsernameStatus::TooLong: error = tr("usernameStatusTooLong").arg(config->getInt("assistant", "username_max_length", -1)); break; case linphone::AccountCreator::UsernameStatus::InvalidCharacters: error = tr("usernameStatusInvalidCharacters") .arg(Utils::coreStringToAppString(config->getString("assistant", "username_regex", ""))); break; case linphone::AccountCreator::UsernameStatus::Invalid: error = tr("usernameStatusInvalid"); break; } return error; } linphone-desktop-4.2.5/linphone-app/src/components/assistant/AssistantModel.hpp000066400000000000000000000074061376717241300300510ustar00rootroot00000000000000/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef ASSISTANT_MODEL_H_ #define ASSISTANT_MODEL_H_ #include #include // ============================================================================= class AssistantModel : public QObject { class Handlers; Q_OBJECT; Q_PROPERTY(QString email READ getEmail WRITE setEmail NOTIFY emailChanged); Q_PROPERTY(QString password READ getPassword WRITE setPassword NOTIFY passwordChanged); Q_PROPERTY(QString countryCode READ getCountryCode WRITE setCountryCode NOTIFY countryCodeChanged); Q_PROPERTY(QString phoneNumber READ getPhoneNumber WRITE setPhoneNumber NOTIFY phoneNumberChanged); Q_PROPERTY(QString username READ getUsername WRITE setUsername NOTIFY usernameChanged); Q_PROPERTY(QString displayName READ getDisplayName WRITE setDisplayName NOTIFY displayNameChanged); Q_PROPERTY(QString activationCode READ getActivationCode WRITE setActivationCode NOTIFY activationCodeChanged); Q_PROPERTY(QString configFilename READ getConfigFilename WRITE setConfigFilename NOTIFY configFilenameChanged); public: AssistantModel (QObject *parent = Q_NULLPTR); Q_INVOKABLE void activate (); Q_INVOKABLE void create (); Q_INVOKABLE void login (); Q_INVOKABLE void reset (); Q_INVOKABLE bool addOtherSipAccount (const QVariantMap &map); signals: void emailChanged (const QString &email, const QString &error); void passwordChanged (const QString &password, const QString &error); void countryCodeChanged (const QString &countryCode); void phoneNumberChanged (const QString &phoneNumber, const QString &error); void usernameChanged (const QString &username, const QString &error); void displayNameChanged (const QString &displayName, const QString &error); void activationCodeChanged (const QString &activationCode); void activateStatusChanged (const QString &error); void createStatusChanged (const QString &error); void loginStatusChanged (const QString &error); void recoverStatusChanged (const QString &error); void configFilenameChanged (const QString &configFilename); private: QString getEmail () const; void setEmail (const QString &email); QString getPassword () const; void setPassword (const QString &password); QString getCountryCode () const; void setCountryCode (const QString &countryCode); QString getPhoneNumber () const; void setPhoneNumber (const QString &phoneNumber); QString getUsername () const; void setUsername (const QString &username); QString getDisplayName () const; void setDisplayName (const QString &displayName); QString getActivationCode () const; void setActivationCode (const QString &activationCode); QString getConfigFilename () const; void setConfigFilename (const QString &configFilename); QString mapAccountCreatorUsernameStatusToString (linphone::AccountCreator::UsernameStatus status) const; QString mCountryCode; QString mConfigFilename; std::shared_ptr mAccountCreator; std::shared_ptr mHandlers; }; #endif // ASSISTANT_MODEL_H_ linphone-desktop-4.2.5/linphone-app/src/components/authentication/000077500000000000000000000000001376717241300254055ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/src/components/authentication/AuthenticationNotifier.cpp000066400000000000000000000033661376717241300326000ustar00rootroot00000000000000/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "components/core/CoreHandlers.hpp" #include "components/core/CoreManager.hpp" #include "utils/Utils.hpp" #include "AuthenticationNotifier.hpp" // ============================================================================= using namespace std; AuthenticationNotifier::AuthenticationNotifier (QObject *parent) : QObject(parent) { QObject::connect( CoreManager::getInstance()->getHandlers().get(), &CoreHandlers::authenticationRequested, this, &AuthenticationNotifier::handleAuthenticationRequested ); } void AuthenticationNotifier::handleAuthenticationRequested (const shared_ptr &authInfo) { emit authenticationRequested( QVariant::fromValue(authInfo), Utils::coreStringToAppString(authInfo->getRealm()), QStringLiteral("%1@%2").arg( QString::fromStdString(authInfo->getUsername()) ).arg( Utils::coreStringToAppString(authInfo->getDomain()) ), Utils::coreStringToAppString(authInfo->getUserid()) ); } linphone-desktop-4.2.5/linphone-app/src/components/authentication/AuthenticationNotifier.hpp000066400000000000000000000027271376717241300326050ustar00rootroot00000000000000/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef AUTHENTICATION_NOTIFIER_H_ #define AUTHENTICATION_NOTIFIER_H_ #include #include // ============================================================================= namespace linphone { class AuthInfo; } class AuthenticationNotifier : public QObject { Q_OBJECT; public: AuthenticationNotifier (QObject *parent = Q_NULLPTR); signals: void authenticationRequested (const QVariant &authInfo, const QString &realm, const QString &sipAddress, const QString &userId); private: void handleAuthenticationRequested (const std::shared_ptr &authInfo); }; Q_DECLARE_METATYPE(std::shared_ptr); #endif // AUTHENTICATION_NOTIFIER_H_ linphone-desktop-4.2.5/linphone-app/src/components/call/000077500000000000000000000000001376717241300233015ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/src/components/call/CallModel.cpp000066400000000000000000000625511376717241300256520ustar00rootroot00000000000000/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "CallModel.hpp" #include #include #include #include #include "app/App.hpp" #include "components/calls/CallsListModel.hpp" #include "components/core/CoreHandlers.hpp" #include "components/core/CoreManager.hpp" #include "components/notifier/Notifier.hpp" #include "components/settings/AccountSettingsModel.hpp" #include "components/settings/SettingsModel.hpp" #include "utils/LinphoneUtils.hpp" #include "utils/MediastreamerUtils.hpp" #include "utils/Utils.hpp" // ============================================================================= using namespace std; namespace { constexpr char AutoAnswerObjectName[] = "auto-answer-timer"; } CallModel::CallModel (shared_ptr call) { Q_CHECK_PTR(call); mCall = call; mCall->setData("call-model", *this); updateIsInConference(); CoreManager *coreManager = CoreManager::getInstance(); // Deal with auto-answer. if (!isOutgoing()) { SettingsModel *settings = coreManager->getSettingsModel(); if (settings->getAutoAnswerStatus()) { QTimer *timer = new QTimer(this); timer->setInterval(settings->getAutoAnswerDelay()); timer->setSingleShot(true); timer->setObjectName(AutoAnswerObjectName); QObject::connect(timer, &QTimer::timeout, this, &CallModel::acceptWithAutoAnswerDelay); timer->start(); } } CoreHandlers *coreHandlers = coreManager->getHandlers().get(); QObject::connect( coreHandlers, &CoreHandlers::callStateChanged, this, &CallModel::handleCallStateChanged ); QObject::connect( coreHandlers, &CoreHandlers::callEncryptionChanged, this, &CallModel::handleCallEncryptionChanged ); } CallModel::~CallModel () { mCall->unsetData("call-model"); } // ----------------------------------------------------------------------------- QString CallModel::getPeerAddress () const { return Utils::coreStringToAppString(mCall->getRemoteAddress()->asStringUriOnly()); } QString CallModel::getLocalAddress () const { return Utils::coreStringToAppString(mCall->getCallLog()->getLocalAddress()->asStringUriOnly()); } QString CallModel::getFullPeerAddress () const { return Utils::coreStringToAppString(mCall->getRemoteAddress()->asString()); } QString CallModel::getFullLocalAddress () const { return Utils::coreStringToAppString(mCall->getCallLog()->getLocalAddress()->asString()); } // ----------------------------------------------------------------------------- void CallModel::setRecordFile (const shared_ptr &callParams) { callParams->setRecordFile(Utils::appStringToCoreString( CoreManager::getInstance()->getSettingsModel()->getSavedCallsFolder() .append(generateSavedFilename()) .append(".mkv") )); } void CallModel::setRecordFile (const shared_ptr &callParams, const QString &to) { const QString from( QString::fromStdString( CoreManager::getInstance()->getAccountSettingsModel()->getUsedSipAddress()->getUsername() ) ); callParams->setRecordFile(Utils::appStringToCoreString( CoreManager::getInstance()->getSettingsModel()->getSavedCallsFolder() .append(generateSavedFilename(from, to)) .append(".mkv") )); } // ----------------------------------------------------------------------------- void CallModel::updateStats (const shared_ptr &callStats) { switch (callStats->getType()) { case linphone::StreamType::Text: case linphone::StreamType::Unknown: break; case linphone::StreamType::Audio: updateStats(callStats, mAudioStats); break; case linphone::StreamType::Video: updateStats(callStats, mVideoStats); break; } emit statsUpdated(); } // ----------------------------------------------------------------------------- float CallModel::getSpeakerVolumeGain () const { return mCall->getSpeakerVolumeGain(); } void CallModel::setSpeakerVolumeGain (float volume) { Q_ASSERT(volume >= 0.0f && volume <= 1.0f); mCall->setSpeakerVolumeGain(volume); emit speakerVolumeGainChanged(getSpeakerVolumeGain()); } float CallModel::getMicroVolumeGain () const { return mCall->getMicrophoneVolumeGain(); } void CallModel::setMicroVolumeGain (float volume) { Q_ASSERT(volume >= 0.0f && volume <= 1.0f); mCall->setMicrophoneVolumeGain(volume); emit microVolumeGainChanged(getMicroVolumeGain()); } // ----------------------------------------------------------------------------- void CallModel::notifyCameraFirstFrameReceived (unsigned int width, unsigned int height) { if (mNotifyCameraFirstFrameReceived) { mNotifyCameraFirstFrameReceived = false; emit cameraFirstFrameReceived(width, height); } } // ----------------------------------------------------------------------------- void CallModel::accept () { accept(false); } void CallModel::acceptWithVideo () { accept(true); } void CallModel::terminate () { CoreManager *core = CoreManager::getInstance(); core->lockVideoRender(); mCall->terminate(); core->unlockVideoRender(); } // ----------------------------------------------------------------------------- void CallModel::askForTransfer () { CoreManager::getInstance()->getCallsListModel()->askForTransfer(this); } bool CallModel::transferTo (const QString &sipAddress) { bool status = !!mCall->transfer(Utils::appStringToCoreString(sipAddress)); if (status) qWarning() << QStringLiteral("Unable to transfer: `%1`.").arg(sipAddress); return status; } // ----------------------------------------------------------------------------- void CallModel::acceptVideoRequest () { shared_ptr params = CoreManager::getInstance()->getCore()->createCallParams(mCall); params->enableVideo(true); mCall->acceptUpdate(params); } void CallModel::rejectVideoRequest () { shared_ptr params = CoreManager::getInstance()->getCore()->createCallParams(mCall); params->enableVideo(false); mCall->acceptUpdate(params); } void CallModel::takeSnapshot () { static QString oldName; QString newName(generateSavedFilename().append(".jpg")); if (newName == oldName) { qWarning() << QStringLiteral("Unable to take snapshot. Wait one second."); return; } oldName = newName; qInfo() << QStringLiteral("Take snapshot of call:") << this; const QString filePath(CoreManager::getInstance()->getSettingsModel()->getSavedScreenshotsFolder().append(newName)); mCall->takeVideoSnapshot(Utils::appStringToCoreString(filePath)); App::getInstance()->getNotifier()->notifySnapshotWasTaken(filePath); } void CallModel::startRecording () { if (mRecording) return; qInfo() << QStringLiteral("Start recording call:") << this; mCall->startRecording(); mRecording = true; emit recordingChanged(true); } void CallModel::stopRecording () { if (!mRecording) return; qInfo() << QStringLiteral("Stop recording call:") << this; mRecording = false; mCall->stopRecording(); App::getInstance()->getNotifier()->notifyRecordingCompleted( Utils::coreStringToAppString(mCall->getParams()->getRecordFile()) ); emit recordingChanged(false); } // ----------------------------------------------------------------------------- void CallModel::handleCallEncryptionChanged (const shared_ptr &call) { if (call == mCall) emit securityUpdated(); } void CallModel::handleCallStateChanged (const shared_ptr &call, linphone::Call::State state) { if (call != mCall) return; updateIsInConference(); switch (state) { case linphone::Call::State::Error: case linphone::Call::State::End: setCallErrorFromReason(call->getReason()); stopAutoAnswerTimer(); stopRecording(); mPausedByRemote = false; break; case linphone::Call::State::StreamsRunning: { if (!mWasConnected && CoreManager::getInstance()->getSettingsModel()->getAutomaticallyRecordCalls()) { startRecording(); mWasConnected = true; } mPausedByRemote = false; break; } case linphone::Call::State::Connected: case linphone::Call::State::Referred: case linphone::Call::State::Released: mPausedByRemote = false; break; case linphone::Call::State::PausedByRemote: mNotifyCameraFirstFrameReceived = true; mPausedByRemote = true; break; case linphone::Call::State::Pausing: mNotifyCameraFirstFrameReceived = true; mPausedByUser = true; break; case linphone::Call::State::Resuming: mPausedByUser = false; break; case linphone::Call::State::UpdatedByRemote: if (!mCall->getCurrentParams()->videoEnabled() && mCall->getRemoteParams()->videoEnabled()) { mCall->deferUpdate(); emit videoRequested(); } break; case linphone::Call::State::Idle: case linphone::Call::State::IncomingReceived: case linphone::Call::State::OutgoingInit: case linphone::Call::State::OutgoingProgress: case linphone::Call::State::OutgoingRinging: case linphone::Call::State::OutgoingEarlyMedia: case linphone::Call::State::Paused: case linphone::Call::State::IncomingEarlyMedia: case linphone::Call::State::Updating: case linphone::Call::State::EarlyUpdatedByRemote: case linphone::Call::State::EarlyUpdating: break; } emit statusChanged(getStatus()); } // ----------------------------------------------------------------------------- void CallModel::accept (bool withVideo) { stopAutoAnswerTimer(); CoreManager *coreManager = CoreManager::getInstance(); QQuickWindow *callsWindow = App::getInstance()->getCallsWindow(); if (callsWindow) { if (coreManager->getSettingsModel()->getKeepCallsWindowInBackground()) { if (!callsWindow->isVisible()) callsWindow->showMinimized(); } else App::smartShowWindow(callsWindow); } qApp->processEvents(); // Process GUI events before accepting in order to be synchronized with Call objects and be ready to get SDK events shared_ptr core = coreManager->getCore(); shared_ptr params = core->createCallParams(mCall); params->enableVideo(withVideo); setRecordFile(params); mCall->acceptWithParams(params); } // ----------------------------------------------------------------------------- void CallModel::updateIsInConference () { if (mIsInConference != mCall->getCurrentParams()->getLocalConferenceMode()) { mIsInConference = !mIsInConference; } emit isInConferenceChanged(mIsInConference); } // ----------------------------------------------------------------------------- void CallModel::stopAutoAnswerTimer () const { QTimer *timer = findChild(AutoAnswerObjectName, Qt::FindDirectChildrenOnly); if (timer) { timer->stop(); timer->deleteLater(); } } // ----------------------------------------------------------------------------- CallModel::CallStatus CallModel::getStatus () const { switch (mCall->getState()) { case linphone::Call::State::Connected: case linphone::Call::State::StreamsRunning: return CallStatusConnected; case linphone::Call::State::End: case linphone::Call::State::Error: case linphone::Call::State::Referred: case linphone::Call::State::Released: return CallStatusEnded; case linphone::Call::State::Paused: case linphone::Call::State::PausedByRemote: case linphone::Call::State::Pausing: case linphone::Call::State::Resuming: return CallStatusPaused; case linphone::Call::State::Updating: case linphone::Call::State::UpdatedByRemote: return mPausedByRemote ? CallStatusPaused : CallStatusConnected; case linphone::Call::State::EarlyUpdatedByRemote: case linphone::Call::State::EarlyUpdating: case linphone::Call::State::Idle: case linphone::Call::State::IncomingEarlyMedia: case linphone::Call::State::IncomingReceived: case linphone::Call::State::OutgoingEarlyMedia: case linphone::Call::State::OutgoingInit: case linphone::Call::State::OutgoingProgress: case linphone::Call::State::OutgoingRinging: break; } return mCall->getDir() == linphone::Call::Dir::Incoming ? CallStatusIncoming : CallStatusOutgoing; } // ----------------------------------------------------------------------------- void CallModel::acceptWithAutoAnswerDelay () { CoreManager *coreManager = CoreManager::getInstance(); SettingsModel *settingsModel = coreManager->getSettingsModel(); // Use auto-answer if activated and it's the only call. if (settingsModel->getAutoAnswerStatus() && coreManager->getCore()->getCallsNb() == 1) { if (mCall->getRemoteParams()->videoEnabled() && settingsModel->getAutoAnswerVideoStatus() && settingsModel->getVideoSupported()) acceptWithVideo(); else accept(); } } // ----------------------------------------------------------------------------- QString CallModel::getCallError () const { return mCallError; } void CallModel::setCallErrorFromReason (linphone::Reason reason) { switch (reason) { case linphone::Reason::Declined: mCallError = tr("callErrorDeclined"); break; case linphone::Reason::NotFound: mCallError = tr("callErrorNotFound"); break; case linphone::Reason::Busy: mCallError = tr("callErrorBusy"); break; case linphone::Reason::NotAcceptable: mCallError = tr("callErrorNotAcceptable"); break; default: break; } if (!mCallError.isEmpty()) qInfo() << QStringLiteral("Call terminated with error (%1):").arg(mCallError) << this; emit callErrorChanged(mCallError); } // ----------------------------------------------------------------------------- int CallModel::getDuration () const { return mCall->getDuration(); } float CallModel::getQuality () const { return mCall->getCurrentQuality(); } // ----------------------------------------------------------------------------- float CallModel::getSpeakerVu () const { if (mCall->getState() == linphone::Call::State::StreamsRunning) return MediastreamerUtils::computeVu(mCall->getPlayVolume()); return 0.0; } float CallModel::getMicroVu () const { if (mCall->getState() == linphone::Call::State::StreamsRunning) return MediastreamerUtils::computeVu(mCall->getRecordVolume()); return 0.0; } // ----------------------------------------------------------------------------- bool CallModel::getSpeakerMuted () const { return mCall->getSpeakerMuted(); } void CallModel::setSpeakerMuted (bool status) { if (status == getSpeakerMuted()) return; mCall->setSpeakerMuted(status); emit speakerMutedChanged(getSpeakerMuted()); } // ----------------------------------------------------------------------------- bool CallModel::getMicroMuted () const { return mCall->getMicrophoneMuted(); } void CallModel::setMicroMuted (bool status) { if (status == getMicroMuted()) return; mCall->setMicrophoneMuted(status); emit microMutedChanged(getMicroMuted()); } // ----------------------------------------------------------------------------- bool CallModel::getPausedByUser () const { return mPausedByUser; } void CallModel::setPausedByUser (bool status) { switch (mCall->getState()) { case linphone::Call::State::Connected: case linphone::Call::State::StreamsRunning: case linphone::Call::State::Paused: case linphone::Call::State::PausedByRemote: break; default: return; } if (status) { if (!mPausedByUser) mCall->pause(); return; } if (mPausedByUser) mCall->resume(); } // ----------------------------------------------------------------------------- bool CallModel::getVideoEnabled () const { shared_ptr params = mCall->getCurrentParams(); return params && params->videoEnabled() && getStatus() == CallStatusConnected; } void CallModel::setVideoEnabled (bool status) { shared_ptr core = CoreManager::getInstance()->getCore(); if (!core->videoSupported()) { qWarning() << QStringLiteral("Unable to update video call property. (Video not supported.)"); return; } switch (mCall->getState()) { case linphone::Call::State::Connected: case linphone::Call::State::StreamsRunning: break; default: return; } if (status == getVideoEnabled()) return; shared_ptr params = core->createCallParams(mCall); params->enableVideo(status); mCall->update(params); } // ----------------------------------------------------------------------------- bool CallModel::getUpdating () const { switch (mCall->getState()) { case linphone::Call::State::Connected: case linphone::Call::State::StreamsRunning: case linphone::Call::State::Paused: case linphone::Call::State::PausedByRemote: return false; default: break; } return true; } bool CallModel::getRecording () const { return mRecording; } // ----------------------------------------------------------------------------- void CallModel::sendDtmf (const QString &dtmf) { const char key = dtmf.constData()[0].toLatin1(); qInfo() << QStringLiteral("Send dtmf: `%1`.").arg(key); mCall->sendDtmf(key); CoreManager::getInstance()->getCore()->playDtmf(key, DtmfSoundDelay); } // ----------------------------------------------------------------------------- void CallModel::verifyAuthenticationToken (bool verify) { mCall->setAuthenticationTokenVerified(verify); emit securityUpdated(); } // ----------------------------------------------------------------------------- void CallModel::updateStreams () { mCall->update(nullptr); } void CallModel::toggleSpeakerMute(){ setSpeakerMuted(!getSpeakerMuted()); } // ----------------------------------------------------------------------------- CallModel::CallEncryption CallModel::getEncryption () const { return static_cast(mCall->getCurrentParams()->getMediaEncryption()); } bool CallModel::isSecured () const { shared_ptr params = mCall->getCurrentParams(); linphone::MediaEncryption encryption = params->getMediaEncryption(); return ( encryption == linphone::MediaEncryption::ZRTP && mCall->getAuthenticationTokenVerified() ) || encryption == linphone::MediaEncryption::SRTP || encryption == linphone::MediaEncryption::DTLS; } // ----------------------------------------------------------------------------- QString CallModel::getLocalSas () const { QString token = Utils::coreStringToAppString(mCall->getAuthenticationToken()); return mCall->getDir() == linphone::Call::Dir::Incoming ? token.left(2).toUpper() : token.right(2).toUpper(); } QString CallModel::getRemoteSas () const { QString token = Utils::coreStringToAppString(mCall->getAuthenticationToken()); return mCall->getDir() != linphone::Call::Dir::Incoming ? token.left(2).toUpper() : token.right(2).toUpper(); } // ----------------------------------------------------------------------------- QString CallModel::getSecuredString () const { switch (mCall->getCurrentParams()->getMediaEncryption()) { case linphone::MediaEncryption::SRTP: return QStringLiteral("SRTP"); case linphone::MediaEncryption::ZRTP: return QStringLiteral("ZRTP"); case linphone::MediaEncryption::DTLS: return QStringLiteral("DTLS"); case linphone::MediaEncryption::None: break; } return QString(""); } // ----------------------------------------------------------------------------- QVariantList CallModel::getAudioStats () const { return mAudioStats; } QVariantList CallModel::getVideoStats () const { return mVideoStats; } // ----------------------------------------------------------------------------- static inline QVariantMap createStat (const QString &key, const QString &value) { QVariantMap m; m["key"] = key; m["value"] = value; return m; } void CallModel::updateStats (const shared_ptr &callStats, QVariantList &statsList) { shared_ptr params = mCall->getCurrentParams(); shared_ptr payloadType; switch (callStats->getType()) { case linphone::StreamType::Audio: payloadType = params->getUsedAudioPayloadType(); break; case linphone::StreamType::Video: payloadType = params->getUsedVideoPayloadType(); break; default: return; } QString family; switch (callStats->getIpFamilyOfRemote()) { case linphone::AddressFamily::Inet: family = QStringLiteral("IPv4"); break; case linphone::AddressFamily::Inet6: family = QStringLiteral("IPv6"); break; default: family = QStringLiteral("Unknown"); break; } statsList.clear(); statsList << createStat(tr("callStatsCodec"), payloadType ? QStringLiteral("%1 / %2kHz").arg(Utils::coreStringToAppString(payloadType->getMimeType())).arg(payloadType->getClockRate() / 1000) : QString("")); statsList << createStat(tr("callStatsUploadBandwidth"), QStringLiteral("%1 kbits/s").arg(int(callStats->getUploadBandwidth()))); statsList << createStat(tr("callStatsDownloadBandwidth"), QStringLiteral("%1 kbits/s").arg(int(callStats->getDownloadBandwidth()))); statsList << createStat(tr("callStatsIceState"), iceStateToString(callStats->getIceState())); statsList << createStat(tr("callStatsIpFamily"), family); statsList << createStat(tr("callStatsSenderLossRate"), QStringLiteral("%1 %").arg(static_cast(callStats->getSenderLossRate()))); statsList << createStat(tr("callStatsReceiverLossRate"), QStringLiteral("%1 %").arg(static_cast(callStats->getReceiverLossRate()))); switch (callStats->getType()) { case linphone::StreamType::Audio: statsList << createStat(tr("callStatsJitterBuffer"), QStringLiteral("%1 ms").arg(callStats->getJitterBufferSizeMs())); break; case linphone::StreamType::Video: { statsList << createStat(tr("callStatsEstimatedDownloadBandwidth"), QStringLiteral("%1 kbits/s").arg(int(callStats->getEstimatedDownloadBandwidth()))); const QString sentVideoDefinitionName = Utils::coreStringToAppString(params->getSentVideoDefinition()->getName()); const QString sentVideoDefinition = QStringLiteral("%1x%2") .arg(params->getSentVideoDefinition()->getWidth()) .arg(params->getSentVideoDefinition()->getHeight()); statsList << createStat(tr("callStatsSentVideoDefinition"), sentVideoDefinition == sentVideoDefinitionName ? sentVideoDefinition : QStringLiteral("%1 (%2)").arg(sentVideoDefinition).arg(sentVideoDefinitionName)); const QString receivedVideoDefinitionName = Utils::coreStringToAppString(params->getReceivedVideoDefinition()->getName()); const QString receivedVideoDefinition = QString("%1x%2") .arg(params->getReceivedVideoDefinition()->getWidth()) .arg(params->getReceivedVideoDefinition()->getHeight()); statsList << createStat(tr("callStatsReceivedVideoDefinition"), receivedVideoDefinition == receivedVideoDefinitionName ? receivedVideoDefinition : QString("%1 (%2)").arg(receivedVideoDefinition).arg(receivedVideoDefinitionName)); statsList << createStat(tr("callStatsReceivedFramerate"), QStringLiteral("%1 FPS").arg(static_cast(params->getReceivedFramerate()))); statsList << createStat(tr("callStatsSentFramerate"), QStringLiteral("%1 FPS").arg(static_cast(params->getSentFramerate()))); } break; default: break; } } // ----------------------------------------------------------------------------- QString CallModel::iceStateToString (linphone::IceState state) const { switch (state) { case linphone::IceState::NotActivated: return tr("iceStateNotActivated"); case linphone::IceState::Failed: return tr("iceStateFailed"); case linphone::IceState::InProgress: return tr("iceStateInProgress"); case linphone::IceState::ReflexiveConnection: return tr("iceStateReflexiveConnection"); case linphone::IceState::HostConnection: return tr("iceStateHostConnection"); case linphone::IceState::RelayConnection: return tr("iceStateRelayConnection"); } return tr("iceStateInvalid"); } // ----------------------------------------------------------------------------- QString CallModel::generateSavedFilename () const { const shared_ptr callLog(mCall->getCallLog()); return generateSavedFilename( QString::fromStdString(callLog->getFromAddress()->getUsername()), QString::fromStdString(callLog->getToAddress()->getUsername()) ); } QString CallModel::generateSavedFilename (const QString &from, const QString &to) { auto escape = [](const QString &str) { constexpr char ReservedCharacters[] = "<>:\"/\\|\\?\\*"; static QRegularExpression regexp(ReservedCharacters); return QString(str).replace(regexp, ""); }; return QStringLiteral("%1_%2_%3") .arg(QDateTime::currentDateTime().toString("yyyy-MM-dd_hh-mm-ss")) .arg(escape(from)) .arg(escape(to)); } linphone-desktop-4.2.5/linphone-app/src/components/call/CallModel.hpp000066400000000000000000000167011376717241300256530ustar00rootroot00000000000000/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef CALL_MODEL_H_ #define CALL_MODEL_H_ #include #include // ============================================================================= class CallModel : public QObject { Q_OBJECT; Q_PROPERTY(QString peerAddress READ getPeerAddress CONSTANT); Q_PROPERTY(QString localAddress READ getLocalAddress CONSTANT); Q_PROPERTY(QString fullPeerAddress READ getFullPeerAddress CONSTANT); Q_PROPERTY(QString fullLocalAddress READ getFullLocalAddress CONSTANT); Q_PROPERTY(CallStatus status READ getStatus NOTIFY statusChanged); Q_PROPERTY(QString callError READ getCallError NOTIFY callErrorChanged); Q_PROPERTY(bool isOutgoing READ isOutgoing CONSTANT); Q_PROPERTY(bool isInConference READ isInConference NOTIFY isInConferenceChanged); Q_PROPERTY(int duration READ getDuration CONSTANT); // Constants but called with a timer in qml. Q_PROPERTY(float quality READ getQuality CONSTANT); Q_PROPERTY(float speakerVu READ getSpeakerVu CONSTANT); Q_PROPERTY(float microVu READ getMicroVu CONSTANT); Q_PROPERTY(bool speakerMuted READ getSpeakerMuted WRITE setSpeakerMuted NOTIFY speakerMutedChanged); Q_PROPERTY(bool microMuted READ getMicroMuted WRITE setMicroMuted NOTIFY microMutedChanged); Q_PROPERTY(bool pausedByUser READ getPausedByUser WRITE setPausedByUser NOTIFY statusChanged); Q_PROPERTY(bool videoEnabled READ getVideoEnabled WRITE setVideoEnabled NOTIFY statusChanged); Q_PROPERTY(bool updating READ getUpdating NOTIFY statusChanged) Q_PROPERTY(bool recording READ getRecording NOTIFY recordingChanged); Q_PROPERTY(QVariantList audioStats READ getAudioStats NOTIFY statsUpdated); Q_PROPERTY(QVariantList videoStats READ getVideoStats NOTIFY statsUpdated); Q_PROPERTY(CallEncryption encryption READ getEncryption NOTIFY securityUpdated); Q_PROPERTY(bool isSecured READ isSecured NOTIFY securityUpdated); Q_PROPERTY(QString localSas READ getLocalSas NOTIFY securityUpdated); Q_PROPERTY(QString remoteSas READ getRemoteSas NOTIFY securityUpdated); Q_PROPERTY(QString securedString READ getSecuredString NOTIFY securityUpdated); Q_PROPERTY(float speakerVolumeGain READ getSpeakerVolumeGain WRITE setSpeakerVolumeGain NOTIFY speakerVolumeGainChanged); Q_PROPERTY(float microVolumeGain READ getMicroVolumeGain WRITE setMicroVolumeGain NOTIFY microVolumeGainChanged); public: enum CallStatus { CallStatusConnected, CallStatusEnded, CallStatusIdle, CallStatusIncoming, CallStatusOutgoing, CallStatusPaused }; Q_ENUM(CallStatus); enum CallEncryption { CallEncryptionNone = int(linphone::MediaEncryption::None), CallEncryptionDtls = int(linphone::MediaEncryption::DTLS), CallEncryptionSrtp = int(linphone::MediaEncryption::SRTP), CallEncryptionZrtp = int(linphone::MediaEncryption::ZRTP) }; Q_ENUM(CallEncryption); CallModel (std::shared_ptr call); ~CallModel (); std::shared_ptr getCall () const { return mCall; } QString getPeerAddress () const; QString getLocalAddress () const; QString getFullPeerAddress () const; QString getFullLocalAddress () const; bool isInConference () const { return mIsInConference; } void setRecordFile (const std::shared_ptr &callParams); static void setRecordFile (const std::shared_ptr &callParams, const QString &to); void updateStats (const std::shared_ptr &callStats); void notifyCameraFirstFrameReceived (unsigned int width, unsigned int height); Q_INVOKABLE void accept (); Q_INVOKABLE void acceptWithVideo (); Q_INVOKABLE void terminate (); Q_INVOKABLE void askForTransfer (); Q_INVOKABLE bool transferTo (const QString &sipAddress); Q_INVOKABLE void acceptVideoRequest (); Q_INVOKABLE void rejectVideoRequest (); Q_INVOKABLE void takeSnapshot (); Q_INVOKABLE void startRecording (); Q_INVOKABLE void stopRecording (); Q_INVOKABLE void sendDtmf (const QString &dtmf); Q_INVOKABLE void verifyAuthenticationToken (bool verify); Q_INVOKABLE void updateStreams (); Q_INVOKABLE void toggleSpeakerMute(); static constexpr int DtmfSoundDelay = 200; signals: void callErrorChanged (const QString &callError); void isInConferenceChanged (bool status); void speakerMutedChanged (bool status); void microMutedChanged (bool status); void recordingChanged (bool status); void statsUpdated (); void statusChanged (CallStatus status); void videoRequested (); void securityUpdated (); void speakerVolumeGainChanged (float volume); void microVolumeGainChanged (float volume); void cameraFirstFrameReceived (unsigned int width, unsigned int height); private: void handleCallEncryptionChanged (const std::shared_ptr &call); void handleCallStateChanged (const std::shared_ptr &call, linphone::Call::State state); void accept (bool withVideo); void stopAutoAnswerTimer () const; CallStatus getStatus () const; bool isOutgoing () const { return mCall->getDir() == linphone::Call::Dir::Outgoing; } void updateIsInConference (); void acceptWithAutoAnswerDelay (); QString getCallError () const; void setCallErrorFromReason (linphone::Reason reason); int getDuration () const; float getQuality () const; float getMicroVu () const; float getSpeakerVu () const; bool getSpeakerMuted () const; void setSpeakerMuted (bool status); bool getMicroMuted () const; void setMicroMuted (bool status); bool getPausedByUser () const; void setPausedByUser (bool status); bool getVideoEnabled () const; void setVideoEnabled (bool status); bool getUpdating () const; bool getRecording () const; CallEncryption getEncryption () const; bool isSecured () const; QString getLocalSas () const; QString getRemoteSas () const; QString getSecuredString () const; QVariantList getAudioStats () const; QVariantList getVideoStats () const; void updateStats (const std::shared_ptr &callStats, QVariantList &statsList); QString iceStateToString (linphone::IceState state) const; float getSpeakerVolumeGain () const; void setSpeakerVolumeGain (float volume); float getMicroVolumeGain () const; void setMicroVolumeGain (float volume); QString generateSavedFilename () const; static QString generateSavedFilename (const QString &from, const QString &to); bool mIsInConference = false; bool mPausedByRemote = false; bool mPausedByUser = false; bool mRecording = false; bool mWasConnected = false; bool mNotifyCameraFirstFrameReceived = true; QString mCallError; QVariantList mAudioStats; QVariantList mVideoStats; std::shared_ptr mCall; }; #endif // CALL_MODEL_H_ linphone-desktop-4.2.5/linphone-app/src/components/calls/000077500000000000000000000000001376717241300234645ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/src/components/calls/CallsListModel.cpp000066400000000000000000000237721376717241300270560ustar00rootroot00000000000000/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include #include #include #include "app/App.hpp" #include "components/call/CallModel.hpp" #include "components/conference/ConferenceAddModel.hpp" #include "components/conference/ConferenceHelperModel.hpp" #include "components/core/CoreHandlers.hpp" #include "components/core/CoreManager.hpp" #include "components/settings/SettingsModel.hpp" #include "utils/Utils.hpp" #include "CallsListModel.hpp" // ============================================================================= using namespace std; namespace { // Delay before removing call in ms. constexpr int DelayBeforeRemoveCall = 3000; } static inline int findCallIndex (QList &list, const shared_ptr &call) { auto it = find_if(list.begin(), list.end(), [call](CallModel *callModel) { return call == callModel->getCall(); }); Q_ASSERT(it != list.end()); return int(distance(list.begin(), it)); } static inline int findCallIndex (QList &list, const CallModel &callModel) { return ::findCallIndex(list, callModel.getCall()); } // ----------------------------------------------------------------------------- CallsListModel::CallsListModel (QObject *parent) : QAbstractListModel(parent) { mCoreHandlers = CoreManager::getInstance()->getHandlers(); QObject::connect( mCoreHandlers.get(), &CoreHandlers::callStateChanged, this, &CallsListModel::handleCallStateChanged ); } int CallsListModel::rowCount (const QModelIndex &) const { return mList.count(); } QHash CallsListModel::roleNames () const { QHash roles; roles[Qt::DisplayRole] = "$call"; return roles; } QVariant CallsListModel::data (const QModelIndex &index, int role) const { int row = index.row(); if (!index.isValid() || row < 0 || row >= mList.count()) return QVariant(); if (role == Qt::DisplayRole) return QVariant::fromValue(mList[row]); return QVariant(); } // ----------------------------------------------------------------------------- void CallsListModel::askForTransfer (CallModel *callModel) { emit callTransferAsked(callModel); } // ----------------------------------------------------------------------------- void CallsListModel::launchAudioCall (const QString &sipAddress, const QHash &headers) const { shared_ptr core = CoreManager::getInstance()->getCore(); shared_ptr address = core->interpretUrl(Utils::appStringToCoreString(sipAddress)); if (!address) return; shared_ptr params = core->createCallParams(nullptr); params->enableVideo(false); QHashIterator iterator(headers); while (iterator.hasNext()) { iterator.next(); params->addCustomHeader(Utils::appStringToCoreString(iterator.key()), Utils::appStringToCoreString(iterator.value())); } CallModel::setRecordFile(params, QString::fromStdString(address->getUsername())); shared_ptr currentProxyConfig = core->getDefaultProxyConfig(); if(currentProxyConfig){ if(currentProxyConfig->getState() == linphone::RegistrationState::Ok) core->inviteAddressWithParams(address, params); else{ QObject * context = new QObject(); QObject::connect(CoreManager::getInstance()->getHandlers().get(), &CoreHandlers::registrationStateChanged,context, [address,core,params,currentProxyConfig, context](const std::shared_ptr &proxyConfig, linphone::RegistrationState state) mutable { if(context && proxyConfig==currentProxyConfig && state==linphone::RegistrationState::Ok){ delete context; context = nullptr; core->inviteAddressWithParams(address, params); } }); } }else core->inviteAddressWithParams(address, params); } void CallsListModel::launchVideoCall (const QString &sipAddress) const { shared_ptr core = CoreManager::getInstance()->getCore(); if (!core->videoSupported()) { qWarning() << QStringLiteral("Unable to launch video call. (Video not supported.) Launching audio call..."); launchAudioCall(sipAddress); return; } shared_ptr address = core->interpretUrl(Utils::appStringToCoreString(sipAddress)); if (!address) return; shared_ptr params = core->createCallParams(nullptr); params->enableVideo(true); CallModel::setRecordFile(params, QString::fromStdString(address->getUsername())); core->inviteAddressWithParams(address, params); } // ----------------------------------------------------------------------------- int CallsListModel::getRunningCallsNumber () const { return CoreManager::getInstance()->getCore()->getCallsNb(); } void CallsListModel::terminateAllCalls () const { CoreManager::getInstance()->getCore()->terminateAllCalls(); } // ----------------------------------------------------------------------------- static void joinConference (const shared_ptr &call) { if (call->getToHeader("method") != "join-conference") return; shared_ptr core = CoreManager::getInstance()->getCore(); if (!core->getConference()) { qWarning() << QStringLiteral("Not in a conference. => Responding to `join-conference` as a simple call..."); return; } shared_ptr conference = core->getConference(); const QString conferenceId = Utils::coreStringToAppString(call->getToHeader("conference-id")); if (conference->getId() != Utils::appStringToCoreString(conferenceId)) { qWarning() << QStringLiteral("Trying to join conference with an invalid conference id: `%1`. Responding as a simple call...") .arg(conferenceId); return; } qInfo() << QStringLiteral("Join conference: `%1`.").arg(conferenceId); ConferenceHelperModel helperModel; ConferenceHelperModel::ConferenceAddModel *addModel = helperModel.getConferenceAddModel(); CallModel *callModel = &call->getData("call-model"); callModel->accept(); addModel->addToConference(call->getRemoteAddress()); addModel->update(); } void CallsListModel::handleCallStateChanged (const shared_ptr &call, linphone::Call::State state) { switch (state) { case linphone::Call::State::IncomingReceived: addCall(call); joinConference(call); break; case linphone::Call::State::OutgoingInit: addCall(call); break; case linphone::Call::State::End: case linphone::Call::State::Error: if (call->getCallLog()->getStatus() == linphone::Call::Status::Missed) emit callMissed(&call->getData("call-model")); removeCall(call); break; case linphone::Call::State::StreamsRunning: { int index = findCallIndex(mList, call); emit callRunning(index, &call->getData("call-model")); } break; default: break; } } bool CallsListModel::removeRow (int row, const QModelIndex &parent) { return removeRows(row, 1, parent); } bool CallsListModel::removeRows (int row, int count, const QModelIndex &parent) { int limit = row + count - 1; if (row < 0 || count < 0 || limit >= mList.count()) return false; beginRemoveRows(parent, row, limit); for (int i = 0; i < count; ++i) mList.takeAt(row)->deleteLater(); endRemoveRows(); return true; } // ----------------------------------------------------------------------------- void CallsListModel::addCall (const shared_ptr &call) { if (call->getDir() == linphone::Call::Dir::Outgoing) { QQuickWindow *callsWindow = App::getInstance()->getCallsWindow(); if (callsWindow) { if (CoreManager::getInstance()->getSettingsModel()->getKeepCallsWindowInBackground()) { if (!callsWindow->isVisible()) callsWindow->showMinimized(); } else App::smartShowWindow(callsWindow); } } CallModel *callModel = new CallModel(call); qInfo() << QStringLiteral("Add call:") << callModel->getFullLocalAddress() << callModel->getFullPeerAddress(); App::getInstance()->getEngine()->setObjectOwnership(callModel, QQmlEngine::CppOwnership); // This connection is (only) useful for `CallsListProxyModel`. QObject::connect(callModel, &CallModel::isInConferenceChanged, this, [this, callModel](bool) { int id = findCallIndex(mList, *callModel); emit dataChanged(index(id, 0), index(id, 0)); }); int row = mList.count(); beginInsertRows(QModelIndex(), row, row); mList << callModel; endInsertRows(); } void CallsListModel::removeCall (const shared_ptr &call) { CallModel *callModel; try { callModel = &call->getData("call-model"); } catch (const out_of_range &) { // The call model not exists because the linphone call state // `CallStateIncomingReceived`/`CallStateOutgoingInit` was not notified. qWarning() << QStringLiteral("Unable to find call:") << call.get(); return; } QTimer::singleShot(DelayBeforeRemoveCall, this, [this, callModel] { removeCallCb(callModel); }); } void CallsListModel::removeCallCb (CallModel *callModel) { qInfo() << QStringLiteral("Removing call:") << callModel; int index = mList.indexOf(callModel); if (index == -1 || !removeRow(index)) qWarning() << QStringLiteral("Unable to remove call:") << callModel; } linphone-desktop-4.2.5/linphone-app/src/components/calls/CallsListModel.hpp000066400000000000000000000045701376717241300270560ustar00rootroot00000000000000/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef CALLS_LIST_MODEL_H_ #define CALLS_LIST_MODEL_H_ #include #include // ============================================================================= class CallModel; class CoreHandlers; class CallsListModel : public QAbstractListModel { Q_OBJECT; public: CallsListModel (QObject *parent = Q_NULLPTR); int rowCount (const QModelIndex &index = QModelIndex()) const override; QHash roleNames () const override; QVariant data (const QModelIndex &index, int role = Qt::DisplayRole) const override; void askForTransfer (CallModel *callModel); Q_INVOKABLE void launchAudioCall (const QString &sipAddress, const QHash &headers = {}) const; Q_INVOKABLE void launchVideoCall (const QString &sipAddress) const; Q_INVOKABLE int getRunningCallsNumber () const; Q_INVOKABLE void terminateAllCalls () const; signals: void callRunning (int index, CallModel *callModel); void callTransferAsked (CallModel *callModel); void callMissed (CallModel *callModel); private: bool removeRow (int row, const QModelIndex &parent = QModelIndex()); bool removeRows (int row, int count, const QModelIndex &parent = QModelIndex()) override; void handleCallStateChanged (const std::shared_ptr &call, linphone::Call::State state); void addCall (const std::shared_ptr &call); void removeCall (const std::shared_ptr &call); void removeCallCb (CallModel *callModel); QList mList; std::shared_ptr mCoreHandlers; }; #endif // CALLS_LIST_MODEL_H_ linphone-desktop-4.2.5/linphone-app/src/components/calls/CallsListProxyModel.cpp000066400000000000000000000032161376717241300301070ustar00rootroot00000000000000/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "components/call/CallModel.hpp" #include "components/core/CoreManager.hpp" #include "CallsListModel.hpp" #include "CallsListProxyModel.hpp" // ============================================================================= using namespace std; CallsListProxyModel::CallsListProxyModel (QObject *parent) : QSortFilterProxyModel(parent) { CallsListModel *callsListModel = CoreManager::getInstance()->getCallsListModel(); QObject::connect(callsListModel, &CallsListModel::callRunning, this, [this](int index, CallModel *callModel) { emit callRunning(index, callModel); }); setSourceModel(callsListModel); sort(0); } bool CallsListProxyModel::filterAcceptsRow (int sourceRow, const QModelIndex &sourceParent) const { const QModelIndex index = sourceModel()->index(sourceRow, 0, sourceParent); return !index.data().value()->isInConference(); } linphone-desktop-4.2.5/linphone-app/src/components/calls/CallsListProxyModel.hpp000066400000000000000000000024651376717241300301210ustar00rootroot00000000000000/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef CALLS_LIST_PROXY_MODEL_H_ #define CALLS_LIST_PROXY_MODEL_H_ #include // ============================================================================= class CallModel; class CallsListProxyModel : public QSortFilterProxyModel { Q_OBJECT; public: CallsListProxyModel (QObject *parent = Q_NULLPTR); signals: void callRunning (int index, CallModel *callModel); private: bool filterAcceptsRow (int sourceRow, const QModelIndex &sourceParent) const override; }; #endif // CALLS_LIST_PROXY_MODEL_H_ linphone-desktop-4.2.5/linphone-app/src/components/camera/000077500000000000000000000000001376717241300236165ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/src/components/camera/Camera.cpp000066400000000000000000000143341376717241300255170ustar00rootroot00000000000000/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include #include #include #include #include "components/call/CallModel.hpp" #include "components/core/CoreManager.hpp" #include "MSFunctions.hpp" #include "Camera.hpp" // ============================================================================= using namespace std; namespace { constexpr int MaxFps = 30; } struct ContextInfo { GLuint width; GLuint height; OpenGlFunctions *functions; }; // ----------------------------------------------------------------------------- CameraRenderer::CameraRenderer () { mContextInfo = new ContextInfo(); } CameraRenderer::~CameraRenderer () { qInfo() << QStringLiteral("Delete context info:") << mContextInfo; CoreManager *coreManager = CoreManager::getInstance(); coreManager->lockVideoRender(); shared_ptr core = coreManager->getCore(); if (mIsPreview) { if (core->getNativePreviewWindowId() == mContextInfo) core->setNativePreviewWindowId(nullptr); } else if (mCall && mCall->getNativeVideoWindowId() == mContextInfo) mCall->setNativeVideoWindowId(nullptr); coreManager->unlockVideoRender(); delete mContextInfo; } QOpenGLFramebufferObject *CameraRenderer::createFramebufferObject (const QSize &size) { QOpenGLFramebufferObjectFormat format; format.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil); format.setInternalTextureFormat(GL_RGBA8); format.setSamples(4); CoreManager *coreManager = CoreManager::getInstance(); // It's not the same thread as render. coreManager->lockVideoRender(); mContextInfo->width = GLuint(size.width()); mContextInfo->height = GLuint(size.height()); mContextInfo->functions = MSFunctions::getInstance()->getFunctions(); mUpdateContextInfo = true; updateWindowId(); coreManager->unlockVideoRender(); return new QOpenGLFramebufferObject(size, format); } void CameraRenderer::render () { // Draw with ms filter. { QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions(); f->glClearColor(0.f, 0.f, 0.f, 0.f); f->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); CoreManager *coreManager = CoreManager::getInstance(); coreManager->lockVideoRender(); MSFunctions *msFunctions = MSFunctions::getInstance(); msFunctions->bind(f); if (mIsPreview) coreManager->getCore()->previewOglRender(); else if (mCall) { mCall->oglRender(); if (mNotifyReceivedVideoSize && notifyReceivedVideoSize()) mNotifyReceivedVideoSize = false; } msFunctions->bind(nullptr); coreManager->unlockVideoRender(); } // Synchronize opengl calls with QML. if (mWindow) mWindow->resetOpenGLState(); } void CameraRenderer::synchronize (QQuickFramebufferObject *item) { // No mutex needed here. It's a synchronized area. mWindow = item->window(); Camera *camera = qobject_cast(item); { CallModel *model = camera->getCallModel(); mCall = model ? model->getCall() : nullptr; } mIsPreview = camera->mIsPreview; updateWindowId(); } void CameraRenderer::updateWindowId () { if (!mUpdateContextInfo) return; mUpdateContextInfo = false; qInfo() << "Thread" << QThread::currentThread() << QStringLiteral("Set context info (width: %1, height: %2, is_preview: %3):") .arg(mContextInfo->width).arg(mContextInfo->height).arg(mIsPreview) << mContextInfo; if (mIsPreview) CoreManager::getInstance()->getCore()->setNativePreviewWindowId(mContextInfo); else if (mCall) mCall->setNativeVideoWindowId(mContextInfo); } bool CameraRenderer::notifyReceivedVideoSize () const { shared_ptr videoDefinition = mCall->getCurrentParams()->getReceivedVideoDefinition(); // Can be null if the receiver quickly disconnects. Rare but possible. if (!videoDefinition) return false; unsigned int width = videoDefinition->getWidth(); unsigned int height = videoDefinition->getHeight(); if (width && height) { qInfo() << "Thread" << QThread::currentThread() << QStringLiteral("Received video size (width: %1, height: %2):") .arg(width).arg(height) << mContextInfo; CallModel *callModel = &mCall->getData("call-model"); QTimer::singleShot(0, callModel, [callModel, width, height] { callModel->notifyCameraFirstFrameReceived(width, height); }); return true; } return false; } // ----------------------------------------------------------------------------- Camera::Camera (QQuickItem *parent) : QQuickFramebufferObject(parent) { // The fbo content must be y-mirrored because the ms rendering is y-inverted. setMirrorVertically(true); mRefreshTimer = new QTimer(this); mRefreshTimer->setInterval(1000 / MaxFps); QObject::connect( mRefreshTimer, &QTimer::timeout, this, &QQuickFramebufferObject::update, Qt::DirectConnection ); mRefreshTimer->start(); } QQuickFramebufferObject::Renderer *Camera::createRenderer () const { return new CameraRenderer(); } // ----------------------------------------------------------------------------- CallModel *Camera::getCallModel () const { return mCallModel; } void Camera::setCallModel (CallModel *callModel) { if (mCallModel != callModel) { mCallModel = callModel; update(); emit callChanged(mCallModel); } } bool Camera::getIsPreview () const { return mIsPreview; } void Camera::setIsPreview (bool status) { if (mIsPreview != status) { mIsPreview = status; update(); emit isPreviewChanged(status); } } linphone-desktop-4.2.5/linphone-app/src/components/camera/Camera.hpp000066400000000000000000000046661376717241300255330ustar00rootroot00000000000000/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef CAMERA_H_ #define CAMERA_H_ #include #include // ============================================================================= namespace linphone { class Call; } class CallModel; struct ContextInfo; class CameraRenderer : public QQuickFramebufferObject::Renderer { public: CameraRenderer (); ~CameraRenderer (); protected: QOpenGLFramebufferObject *createFramebufferObject (const QSize &size) override; void render () override; void synchronize (QQuickFramebufferObject *item) override; private: void updateWindowId (); bool notifyReceivedVideoSize () const; ContextInfo *mContextInfo; bool mUpdateContextInfo = false; bool mNotifyReceivedVideoSize = true; bool mIsPreview = false; std::shared_ptr mCall; QQuickWindow *mWindow = nullptr; }; // ----------------------------------------------------------------------------- class Camera : public QQuickFramebufferObject { friend class CameraRenderer; Q_OBJECT; Q_PROPERTY(CallModel * call READ getCallModel WRITE setCallModel NOTIFY callChanged); Q_PROPERTY(bool isPreview READ getIsPreview WRITE setIsPreview NOTIFY isPreviewChanged); public: Camera (QQuickItem *parent = Q_NULLPTR); QQuickFramebufferObject::Renderer *createRenderer () const override; signals: void callChanged (CallModel *callModel); void isPreviewChanged (bool isPreview); private: CallModel *getCallModel () const; void setCallModel (CallModel *callModel); bool getIsPreview () const; void setIsPreview (bool status); bool mIsPreview = false; CallModel *mCallModel = nullptr; QTimer *mRefreshTimer = nullptr; }; #endif // CAMERA_H_ linphone-desktop-4.2.5/linphone-app/src/components/camera/CameraPreview.cpp000066400000000000000000000111431376717241300270540ustar00rootroot00000000000000/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include #include #include #include #include "components/core/CoreManager.hpp" #include "MSFunctions.hpp" #include "CameraPreview.hpp" // ============================================================================= using namespace std; namespace { constexpr int MaxFps = 30; } struct ContextInfo { GLuint width; GLuint height; OpenGlFunctions *functions; }; // ----------------------------------------------------------------------------- CameraPreviewRenderer::CameraPreviewRenderer () { mContextInfo = new ContextInfo(); } CameraPreviewRenderer::~CameraPreviewRenderer () { qInfo() << QStringLiteral("Delete context info:") << mContextInfo; CoreManager *coreManager = CoreManager::getInstance(); coreManager->lockVideoRender(); coreManager->getCore()->setNativePreviewWindowId(nullptr); coreManager->unlockVideoRender(); delete mContextInfo; } QOpenGLFramebufferObject *CameraPreviewRenderer::createFramebufferObject (const QSize &size) { QOpenGLFramebufferObjectFormat format; format.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil); format.setInternalTextureFormat(GL_RGBA8); format.setSamples(4); CoreManager *coreManager = CoreManager::getInstance(); // It's not the same thread as render. coreManager->lockVideoRender(); mContextInfo->width = GLuint(size.width()); mContextInfo->height = GLuint(size.height()); mContextInfo->functions = MSFunctions::getInstance()->getFunctions(); mUpdateContextInfo = true; updateWindowId(); coreManager->unlockVideoRender(); return new QOpenGLFramebufferObject(size, format); } void CameraPreviewRenderer::render () { // Draw with ms filter. { QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions(); f->glClearColor(0.f, 0.f, 0.f, 1.f); f->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); CoreManager *coreManager = CoreManager::getInstance(); coreManager->lockVideoRender(); MSFunctions *msFunctions = MSFunctions::getInstance(); msFunctions->bind(f); coreManager->getCore()->previewOglRender(); msFunctions->bind(nullptr); coreManager->unlockVideoRender(); } // Synchronize opengl calls with QML. if (mWindow) mWindow->resetOpenGLState(); } void CameraPreviewRenderer::synchronize (QQuickFramebufferObject *item) { mWindow = item->window(); } void CameraPreviewRenderer::updateWindowId () { if (!mUpdateContextInfo) return; mUpdateContextInfo = false; qInfo() << "Thread" << QThread::currentThread() << QStringLiteral("Set context info (width: %1, height: %2):") .arg(mContextInfo->width).arg(mContextInfo->height) << mContextInfo; CoreManager::getInstance()->getCore()->setNativePreviewWindowId(mContextInfo); } // ----------------------------------------------------------------------------- QMutex CameraPreview::mCounterMutex; int CameraPreview::mCounter; // ----------------------------------------------------------------------------- CameraPreview::CameraPreview (QQuickItem *parent) : QQuickFramebufferObject(parent) { mCounterMutex.lock(); if (++mCounter == 1) CoreManager::getInstance()->getCore()->enableVideoPreview(true); mCounterMutex.unlock(); // The fbo content must be y-mirrored because the ms rendering is y-inverted. setMirrorVertically(true); mRefreshTimer = new QTimer(this); mRefreshTimer->setInterval(1000 / MaxFps); QObject::connect( mRefreshTimer, &QTimer::timeout, this, &QQuickFramebufferObject::update, Qt::DirectConnection ); mRefreshTimer->start(); } CameraPreview::~CameraPreview () { mCounterMutex.lock(); if (--mCounter == 0) CoreManager::getInstance()->getCore()->enableVideoPreview(false); mCounterMutex.unlock(); } QQuickFramebufferObject::Renderer *CameraPreview::createRenderer () const { return new CameraPreviewRenderer(); } linphone-desktop-4.2.5/linphone-app/src/components/camera/CameraPreview.hpp000066400000000000000000000037051376717241300270660ustar00rootroot00000000000000/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef CAMERA_PREVIEW_H_ #define CAMERA_PREVIEW_H_ #include #include // ============================================================================= class CameraPreview; struct ContextInfo; class CameraPreviewRenderer : public QQuickFramebufferObject::Renderer { friend class CameraPreview; public: CameraPreviewRenderer (); ~CameraPreviewRenderer (); protected: QOpenGLFramebufferObject *createFramebufferObject (const QSize &size) override; void render () override; void synchronize (QQuickFramebufferObject *item) override; private: void updateWindowId (); ContextInfo *mContextInfo; bool mUpdateContextInfo = false; QQuickWindow *mWindow = nullptr; }; // ----------------------------------------------------------------------------- class CameraPreview : public QQuickFramebufferObject { friend class CameraPreviewRenderer; Q_OBJECT; public: CameraPreview (QQuickItem *parent = Q_NULLPTR); ~CameraPreview (); QQuickFramebufferObject::Renderer *createRenderer () const override; private: QTimer *mRefreshTimer = nullptr; static QMutex mCounterMutex; static int mCounter; }; #endif // CAMERA_PREVIEW_H_ linphone-desktop-4.2.5/linphone-app/src/components/camera/MSFunctions.cpp000066400000000000000000000056571376717241300265470ustar00rootroot00000000000000/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "MSFunctions.hpp" // Do not include this header before `QOpenGLFunctions`!!! #include // ============================================================================= MSFunctions *MSFunctions::mInstance; // ----------------------------------------------------------------------------- MSFunctions::MSFunctions () { OpenGlFunctions *f = mFunctions = new OpenGlFunctions(); f->glActiveTexture = qtResolveGlActiveTexture; f->glAttachShader = qtResolveGlAttachShader; f->glBindAttribLocation = qtResolveGlBindAttribLocation; f->glBindTexture = qtResolveGlBindTexture; f->glClear = qtResolveGlClear; f->glClearColor = qtResolveGlClearColor; f->glCompileShader = qtResolveGlCompileShader; f->glCreateProgram = qtResolveGlCreateProgram; f->glCreateShader = qtResolveGlCreateShader; f->glDeleteProgram = qtResolveGlDeleteProgram; f->glDeleteShader = qtResolveGlDeleteShader; f->glDeleteTextures = qtResolveGlDeleteTextures; f->glDisable = qtResolveGlDisable; f->glDrawArrays = qtResolveGlDrawArrays; f->glEnableVertexAttribArray = qtResolveGlEnableVertexAttribArray; f->glGenTextures = qtResolveGlGenTextures; f->glGetError = qtResolveGlGetError; f->glGetProgramInfoLog = qtResolveGlGetProgramInfoLog; f->glGetProgramiv = qtResolveGlGetProgramiv; f->glGetShaderInfoLog = qtResolveGlGetShaderInfoLog; f->glGetShaderiv = qtResolveGlGetShaderiv; f->glGetString = qtResolveGlGetString; f->glGetUniformLocation = qtResolveGlGetUniformLocation; f->glLinkProgram = qtResolveGlLinkProgram; f->glPixelStorei = qtResolveGlPixelStorei; f->glShaderSource = qtResolveGlShaderSource; f->glTexImage2D = qtResolveGlTexImage2D; f->glTexParameteri = qtResolveGlTexParameteri; f->glTexSubImage2D = qtResolveGlTexSubImage2D; f->glUniform1f = qtResolveGlUniform1f; f->glUniform1i = qtResolveGlUniform1i; f->glUniformMatrix4fv = qtResolveGlUniformMatrix4fv; f->glUseProgram = qtResolveGlUseProgram; f->glValidateProgram = qtResolveGlValidateProgram; f->glVertexAttribPointer = qtResolveGlVertexAttribPointer; f->glViewport = qtResolveGlViewport; } MSFunctions::~MSFunctions () { delete mFunctions; } linphone-desktop-4.2.5/linphone-app/src/components/camera/MSFunctions.hpp000066400000000000000000000154651376717241300265520ustar00rootroot00000000000000/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef MS_FUNCTIONS_H_ #define MS_FUNCTIONS_H_ #include #define GL_ASSERT() \ Q_ASSERT(mInstance->mQtFunctions != NULL); \ Q_ASSERT(QOpenGLContext::currentContext()->functions() == mInstance->mQtFunctions); #define GL_CALL(CALL) \ GL_ASSERT() \ mInstance->mQtFunctions->CALL; #define GL_CALL_RET(CALL) \ GL_ASSERT() \ return mInstance->mQtFunctions->CALL; // ============================================================================= struct OpenGlFunctions; class MSFunctions { public: ~MSFunctions (); void bind (QOpenGLFunctions *f) { mQtFunctions = f; // Qt functions. } OpenGlFunctions *getFunctions () { return mFunctions; // Own implementation. } // --------------------------------------------------------------------------- static MSFunctions *getInstance () { if (!mInstance) mInstance = new MSFunctions(); return mInstance; } // --------------------------------------------------------------------------- static void qtResolveGlActiveTexture (GLenum texture) { GL_CALL(glActiveTexture(texture)); } static void qtResolveGlAttachShader (GLuint program, GLuint shader) { GL_CALL(glAttachShader(program, shader)); } static void qtResolveGlBindAttribLocation (GLuint program, GLuint index, const char *name) { GL_CALL(glBindAttribLocation(program, index, name)); } static void qtResolveGlBindTexture (GLenum target, GLuint texture) { GL_CALL(glBindTexture(target, texture)); } static void qtResolveGlClear (GLbitfield mask) { GL_CALL(glClear(mask)); } static void qtResolveGlClearColor (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) { GL_CALL(glClearColor(red, green, blue, alpha)); } static void qtResolveGlCompileShader (GLuint shader) { GL_CALL(glCompileShader(shader)); } static GLuint qtResolveGlCreateProgram () { GL_CALL_RET(glCreateProgram()); } static GLuint qtResolveGlCreateShader (GLenum type) { GL_CALL_RET(glCreateShader(type)); } static void qtResolveGlDeleteProgram (GLuint program) { GL_CALL(glDeleteProgram(program)); } static void qtResolveGlDeleteShader (GLuint shader) { GL_CALL(glDeleteShader(shader)); } static void qtResolveGlDeleteTextures (GLsizei n, const GLuint *textures) { GL_CALL(glDeleteTextures(n, textures)); } static void qtResolveGlDisable (GLenum cap) { GL_CALL(glDisable(cap)); } static void qtResolveGlDrawArrays (GLenum mode, GLint first, GLsizei count) { GL_CALL(glDrawArrays(mode, first, count)); } static void qtResolveGlEnableVertexAttribArray (GLuint index) { GL_CALL(glEnableVertexAttribArray(index)); } static void qtResolveGlGenTextures (GLsizei n, GLuint *textures) { GL_CALL(glGenTextures(n, textures)); } static GLenum qtResolveGlGetError () { GL_CALL_RET(glGetError()); } static void qtResolveGlGetProgramInfoLog (GLuint program, GLsizei bufsize, GLsizei *length, char *infolog) { GL_CALL(glGetProgramInfoLog(program, bufsize, length, infolog)); } static void qtResolveGlGetProgramiv (GLuint program, GLenum pname, GLint *params) { GL_CALL(glGetProgramiv(program, pname, params)); } static void qtResolveGlGetShaderInfoLog (GLuint shader, GLsizei bufsize, GLsizei *length, char *infolog) { GL_CALL(glGetShaderInfoLog(shader, bufsize, length, infolog)); } static void qtResolveGlGetShaderiv (GLuint shader, GLenum pname, GLint *params) { GL_CALL(glGetShaderiv(shader, pname, params)); } static const GLubyte *qtResolveGlGetString (GLenum name) { GL_CALL_RET(glGetString(name)); } static GLint qtResolveGlGetUniformLocation (GLuint program, const char *name) { GL_CALL_RET(glGetUniformLocation(program, name)); } static void qtResolveGlLinkProgram (GLuint program) { GL_CALL(glLinkProgram(program)); } static void qtResolveGlPixelStorei (GLenum pname, GLint param) { GL_CALL(glPixelStorei(pname, param)); } static void qtResolveGlShaderSource (GLuint shader, GLsizei count, const char **string, const GLint *length) { GL_CALL(glShaderSource(shader, count, string, length)); } static void qtResolveGlTexImage2D (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels) { GL_CALL(glTexImage2D(target, level, internalformat, width, height, border, format, type, pixels)); } static void qtResolveGlTexParameteri (GLenum target, GLenum pname, GLint param) { GL_CALL(glTexParameteri(target, pname, param)); } static void qtResolveGlTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels) { GL_CALL(glTexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels)); } static void qtResolveGlUniform1f (GLint location, GLfloat x) { GL_CALL(glUniform1f(location, x)); } static void qtResolveGlUniform1i (GLint location, GLint x) { GL_CALL(glUniform1i(location, x)); } static void qtResolveGlUniformMatrix4fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) { GL_CALL(glUniformMatrix4fv(location, count, transpose, value)); } static void qtResolveGlUseProgram (GLuint program) { GL_CALL(glUseProgram(program)); } static void qtResolveGlValidateProgram (GLuint program) { GL_CALL(glValidateProgram(program)); } static void qtResolveGlVertexAttribPointer (GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void *ptr) { GL_CALL(glVertexAttribPointer(indx, size, type, normalized, stride, ptr)); } static void qtResolveGlViewport (GLint x, GLint y, GLsizei width, GLsizei height) { GL_CALL(glViewport(x, y, width, height)); } // --------------------------------------------------------------------------- private: MSFunctions (); OpenGlFunctions *mFunctions = nullptr; QOpenGLFunctions *mQtFunctions = nullptr; static MSFunctions *mInstance; }; #undef GL_CALL #undef GL_CALL_RET #undef GL_ASSERT #endif // MS_FUNCTIONS_H_ linphone-desktop-4.2.5/linphone-app/src/components/chat/000077500000000000000000000000001376717241300233055ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/src/components/chat/ChatModel.cpp000066400000000000000000000634161376717241300256630ustar00rootroot00000000000000/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include #include #include #include #include #include #include #include #include #include #include #include "app/App.hpp" #include "app/paths/Paths.hpp" #include "app/providers/ThumbnailProvider.hpp" #include "components/core/CoreHandlers.hpp" #include "components/core/CoreManager.hpp" #include "components/notifier/Notifier.hpp" #include "components/settings/SettingsModel.hpp" #include "utils/QExifImageHeader.hpp" #include "utils/Utils.hpp" #include "ChatModel.hpp" // ============================================================================= using namespace std; namespace { constexpr int ThumbnailImageFileWidth = 100; constexpr int ThumbnailImageFileHeight = 100; // In Bytes. constexpr qint64 FileSizeLimit = 524288000; } // MessageAppData is using to parse what's it in Appdata field of a message class MessageAppData { public: MessageAppData(){} MessageAppData(const QString&); QString m_id; QString m_path; QString toString()const; void fromString(const QString& ); static QString toString(const QVector& ); static QVector fromListString(const QString& ); }; MessageAppData::MessageAppData(const QString& p_data) { fromString(p_data); } QString MessageAppData::toString()const { return m_id+':'+m_path; } void MessageAppData::fromString(const QString& p_data) { QStringList fields = p_data.split(':'); if( fields.size() > 1) { m_id = fields[0]; m_path = fields[1]; } } QString MessageAppData::toString(const QVector& p_data) { QString serialization; if( p_data.size() > 0) { serialization = p_data[0].toString(); for(int i = 1 ; i < p_data.size() ; ++i) serialization += ';'+p_data[i].toString(); } return serialization; } QVector MessageAppData::fromListString(const QString& p_data) { QVector data; QStringList files = p_data.split(";"); for(int i = 0 ; i < files.size() ; ++i) data.push_back(MessageAppData(files[i])); return data; } // There is only one file (thumbnail) in appdata static inline MessageAppData getMessageAppData (const shared_ptr &message) { return MessageAppData(Utils::coreStringToAppString(message->getAppdata())); } static inline bool fileWasDownloaded (const shared_ptr &message) { const MessageAppData appData = getMessageAppData(message); return !appData.m_path.isEmpty() && QFileInfo(appData.m_path).isFile(); } // Set the thumbnail as the first content static inline void fillThumbnailProperty (QVariantMap &dest, const shared_ptr &message) { if( !dest.contains("thumbnail")) { MessageAppData thumbnailData = getMessageAppData(message); if( thumbnailData.m_id != "") dest["thumbnail"] = QStringLiteral("image://%1/%2").arg(ThumbnailProvider::ProviderId).arg(thumbnailData.m_id); } } // Create a thumbnail from the first content that have a file and store it in Appdata static inline void createThumbnail (const shared_ptr &message) { if (!message->getAppdata().empty()) return;// Already exist : no need to create one std::list > contents = message->getContents(); if( contents.size() > 0) { MessageAppData thumbnailData; thumbnailData.m_path = Utils::coreStringToAppString(contents.front()->getFilePath()); QImage image(thumbnailData.m_path); if( image.isNull()){// Try to determine format from headers QImageReader reader(thumbnailData.m_path); reader.setDecideFormatFromContent(true); QByteArray format = reader.format(); if(!format.isEmpty()) image = QImage(thumbnailData.m_path, format); } if (!image.isNull()){ int rotation = 0; QExifImageHeader exifImageHeader; if (exifImageHeader.loadFromJpeg(thumbnailData.m_path)) rotation = int(exifImageHeader.value(QExifImageHeader::ImageTag::Orientation).toShort()); QImage thumbnail = image.scaled( ThumbnailImageFileWidth, ThumbnailImageFileHeight, Qt::KeepAspectRatio, Qt::SmoothTransformation ); if (rotation != 0) { QTransform transform; if (rotation == 3 || rotation == 4) transform.rotate(180); else if (rotation == 5 || rotation == 6) transform.rotate(90); else if (rotation == 7 || rotation == 8) transform.rotate(-90); thumbnail = thumbnail.transformed(transform); if (rotation == 2 || rotation == 4 || rotation == 5 || rotation == 7) thumbnail = thumbnail.mirrored(true, false); } QString uuid = QUuid::createUuid().toString(); thumbnailData.m_id = QStringLiteral("%1.jpg").arg(uuid.mid(1, uuid.length() - 2)); if (!thumbnail.save(Utils::coreStringToAppString(Paths::getThumbnailsDirPath()) + thumbnailData.m_id , "jpg", 100)) { qWarning() << QStringLiteral("Unable to create thumbnail of: `%1`.").arg(thumbnailData.m_path); } } message->setAppdata(Utils::appStringToCoreString(thumbnailData.toString())); } } static inline void removeFileMessageThumbnail (const shared_ptr &message) { if (message && message->getFileTransferInformation()) { message->cancelFileTransfer(); MessageAppData thumbnailFile = getMessageAppData(message); if(thumbnailFile.m_id.size() > 0) { QString thumbnailPath = Utils::coreStringToAppString(Paths::getThumbnailsDirPath()) + thumbnailFile.m_id; if (!QFile::remove(thumbnailPath)) qWarning() << QStringLiteral("Unable to remove `%1`.").arg(thumbnailPath); } message->setAppdata("");// Remove completely Thumbnail from the message } } // ----------------------------------------------------------------------------- static inline void fillMessageEntry (QVariantMap &dest, const shared_ptr &message) { std::list> contents = message->getContents(); QString txt; foreach(auto content, contents){ if(content->isText()) txt += content->getStringBuffer().c_str(); } dest["content"] = txt; dest["isOutgoing"] = message->isOutgoing() || message->getState() == linphone::ChatMessage::State::Idle; // Old workaround. // It can exist messages with a not delivered status. It's a linphone core bug. linphone::ChatMessage::State state = message->getState(); if (state == linphone::ChatMessage::State::InProgress) dest["status"] = ChatModel::MessageStatusNotDelivered; else dest["status"] = static_cast(message->getState()); shared_ptr content = message->getFileTransferInformation(); if (content) { dest["fileSize"] = quint64(content->getFileSize()); dest["fileName"] =Utils::coreStringToAppString(content->getName()); if (state==linphone::ChatMessage::State::Displayed) createThumbnail(message); fillThumbnailProperty(dest, message); dest["wasDownloaded"] = ::fileWasDownloaded(message); } } static inline void fillCallStartEntry (QVariantMap &dest, const shared_ptr &callLog) { dest["type"] = ChatModel::CallEntry; dest["timestamp"] = QDateTime::fromMSecsSinceEpoch(callLog->getStartDate() * 1000); dest["isOutgoing"] = callLog->getDir() == linphone::Call::Dir::Outgoing; dest["status"] = static_cast(callLog->getStatus()); dest["isStart"] = true; } static inline void fillCallEndEntry (QVariantMap &dest, const shared_ptr &callLog) { dest["type"] = ChatModel::CallEntry; dest["timestamp"] = QDateTime::fromMSecsSinceEpoch((callLog->getStartDate() + callLog->getDuration()) * 1000); dest["isOutgoing"] = callLog->getDir() == linphone::Call::Dir::Outgoing; dest["status"] = static_cast(callLog->getStatus()); dest["isStart"] = false; } // ----------------------------------------------------------------------------- class ChatModel::MessageHandlers : public linphone::ChatMessageListener { friend class ChatModel; public: MessageHandlers (ChatModel *chatModel) : mChatModel(chatModel) {} private: QList::iterator findMessageEntry (const shared_ptr &message) { return find_if(mChatModel->mEntries.begin(), mChatModel->mEntries.end(), [&message](const ChatEntryData &entry) { return entry.second == message; }); } void signalDataChanged (const QList::iterator &it) { int row = int(distance(mChatModel->mEntries.begin(), it)); emit mChatModel->dataChanged(mChatModel->index(row, 0), mChatModel->index(row, 0)); } shared_ptr onFileTransferSend ( const shared_ptr &, const shared_ptr &, size_t, size_t ) override { qWarning() << "`onFileTransferSend` called."; return nullptr; } void onFileTransferProgressIndication ( const shared_ptr &message, const shared_ptr &, size_t offset, size_t ) override { if (!mChatModel) return; auto it = findMessageEntry(message); if (it == mChatModel->mEntries.end()) return; (*it).first["fileOffset"] = quint64(offset); signalDataChanged(it); } void onMsgStateChanged (const shared_ptr &message, linphone::ChatMessage::State state) override { if (!mChatModel) return; auto it = findMessageEntry(message); if (it == mChatModel->mEntries.end()) return; // File message downloaded. if (state == linphone::ChatMessage::State::FileTransferDone && !message->isOutgoing()) { createThumbnail(message); fillThumbnailProperty((*it).first, message); (*it).first["wasDownloaded"] = true; App::getInstance()->getNotifier()->notifyReceivedFileMessage(message); } (*it).first["status"] = static_cast(state); signalDataChanged(it); } ChatModel *mChatModel; }; // ----------------------------------------------------------------------------- ChatModel::ChatModel (const QString &peerAddress, const QString &localAddress) { CoreManager *coreManager = CoreManager::getInstance(); mCoreHandlers = coreManager->getHandlers(); mMessageHandlers = make_shared(this); setSipAddresses(peerAddress, localAddress); // Rebind lost handlers for(auto i = mEntries.begin() ; i != mEntries.end() ; ++i){ if(i->first["type"] == EntryType::MessageEntry){ shared_ptr message = static_pointer_cast(i->second); message->removeListener(mMessageHandlers);// Remove old listener if already exists message->addListener(mMessageHandlers); } } { CoreHandlers *coreHandlers = mCoreHandlers.get(); QObject::connect(coreHandlers, &CoreHandlers::messageReceived, this, &ChatModel::handleMessageReceived); QObject::connect(coreHandlers, &CoreHandlers::callStateChanged, this, &ChatModel::handleCallStateChanged); QObject::connect(coreHandlers, &CoreHandlers::isComposingChanged, this, &ChatModel::handleIsComposingChanged); } } ChatModel::~ChatModel () { mMessageHandlers->mChatModel = nullptr; } QHash ChatModel::roleNames () const { QHash roles; roles[Roles::ChatEntry] = "$chatEntry"; roles[Roles::SectionDate] = "$sectionDate"; return roles; } int ChatModel::rowCount (const QModelIndex &) const { return mEntries.count(); } QVariant ChatModel::data (const QModelIndex &index, int role) const { int row = index.row(); if (!index.isValid() || row < 0 || row >= mEntries.count()) return QVariant(); switch (role) { case Roles::ChatEntry: { auto &data = mEntries[row].first; if (data.contains("type") && data["type"]==EntryType::MessageEntry && !data.contains("content")) fillMessageEntry(data, static_pointer_cast(mEntries[row].second)); return QVariant::fromValue(data); } case Roles::SectionDate: return QVariant::fromValue(mEntries[row].first["timestamp"].toDate()); } return QVariant(); } bool ChatModel::removeRow (int row, const QModelIndex &) { return removeRows(row, 1); } bool ChatModel::removeRows (int row, int count, const QModelIndex &parent) { int limit = row + count - 1; if (row < 0 || count < 0 || limit >= mEntries.count()) return false; beginRemoveRows(parent, row, limit); for (int i = 0; i < count; ++i) { removeEntry(mEntries[row]); mEntries.removeAt(row); } endRemoveRows(); if (mEntries.count() == 0) emit allEntriesRemoved(); else if (limit == mEntries.count()) emit lastEntryRemoved(); emit focused();// Removing rows is like having focus. Don't wait asynchronous events. return true; } QString ChatModel::getPeerAddress () const { return Utils::coreStringToAppString( mChatRoom->getPeerAddress()->asStringUriOnly() ); } QString ChatModel::getLocalAddress () const { return Utils::coreStringToAppString( mChatRoom->getLocalAddress()->asStringUriOnly() ); } QString ChatModel::getFullPeerAddress () const { return Utils::coreStringToAppString( mChatRoom->getPeerAddress()->asString() ); } QString ChatModel::getFullLocalAddress () const { return Utils::coreStringToAppString( mChatRoom->getLocalAddress()->asString() ); } void ChatModel::setSipAddresses (const QString &peerAddress, const QString &localAddress) { shared_ptr core = CoreManager::getInstance()->getCore(); shared_ptr factory(linphone::Factory::get()); mChatRoom = core->getChatRoom( factory->createAddress(Utils::appStringToCoreString(peerAddress)), factory->createAddress(Utils::appStringToCoreString(localAddress)) ); Q_ASSERT(mChatRoom); handleIsComposingChanged(mChatRoom); // Get messages. mEntries.clear(); QElapsedTimer timer; timer.start(); for (auto &message : mChatRoom->getHistory(0)) mEntries << qMakePair( QVariantMap{ { "type", EntryType::MessageEntry }, { "timestamp", QDateTime::fromMSecsSinceEpoch(message->getTime() * 1000) } }, static_pointer_cast(message) ); // Get calls. for (auto &callLog : core->getCallHistory(mChatRoom->getPeerAddress(), mChatRoom->getLocalAddress())) insertCall(callLog); qInfo() << QStringLiteral("ChatModel (%1, %2) loaded in %3 milliseconds.") .arg(peerAddress).arg(localAddress).arg(timer.elapsed()); } bool ChatModel::getIsRemoteComposing () const { return mIsRemoteComposing; } // ----------------------------------------------------------------------------- void ChatModel::removeEntry (int id) { qInfo() << QStringLiteral("Removing chat entry: %1 of (%2, %3).") .arg(id).arg(getPeerAddress()).arg(getLocalAddress()); if (!removeRow(id)) qWarning() << QStringLiteral("Unable to remove chat entry: %1").arg(id); } void ChatModel::removeAllEntries () { qInfo() << QStringLiteral("Removing all chat entries of: (%1, %2).") .arg(getPeerAddress()).arg(getLocalAddress()); beginResetModel(); for (auto &entry : mEntries) removeEntry(entry); mEntries.clear(); endResetModel(); emit allEntriesRemoved(); emit focused();// Removing all entries is like having focus. Don't wait asynchronous events. } // ----------------------------------------------------------------------------- void ChatModel::sendMessage (const QString &message) { shared_ptr _message = mChatRoom->createMessage(""); _message->getContents().begin()->get()->setStringBuffer(message.toUtf8().toStdString()); _message->removeListener(mMessageHandlers);// Remove old listener if already exists _message->addListener(mMessageHandlers); insertMessageAtEnd(_message); _message->send(); emit messageSent(_message); } void ChatModel::resendMessage (int id) { if (id < 0 || id > mEntries.count()) { qWarning() << QStringLiteral("Entry %1 not exists.").arg(id); return; } const ChatEntryData entry = mEntries[id]; const QVariantMap map = entry.first; if (map["type"] != EntryType::MessageEntry) { qWarning() << QStringLiteral("Unable to resend entry %1. It's not a message.").arg(id); return; } switch (map["status"].toInt()) { case MessageStatusFileTransferError: case MessageStatusNotDelivered: { shared_ptr message = static_pointer_cast(entry.second); message->removeListener(mMessageHandlers);// Remove old listener if already exists message->addListener(mMessageHandlers); message->send(); break; } default: qWarning() << QStringLiteral("Unable to resend message: %1. Bad state.").arg(id); } } void ChatModel::sendFileMessage (const QString &path) { QFile file(path); if (!file.exists()) return; qint64 fileSize = file.size(); if (fileSize > FileSizeLimit) { qWarning() << QStringLiteral("Unable to send file. (Size limit=%1)").arg(FileSizeLimit); return; } shared_ptr content = CoreManager::getInstance()->getCore()->createContent(); { QStringList mimeType = QMimeDatabase().mimeTypeForFile(path).name().split('/'); if (mimeType.length() != 2) { qWarning() << QStringLiteral("Unable to get supported mime type for: `%1`.").arg(path); return; } content->setType(Utils::appStringToCoreString(mimeType[0])); content->setSubtype(Utils::appStringToCoreString(mimeType[1])); } content->setSize(size_t(fileSize)); content->setName(Utils::appStringToCoreString( QFileInfo(file).fileName())); shared_ptr message = mChatRoom->createFileTransferMessage(content); message->getContents().front()->setFilePath(Utils::appStringToCoreString(path)); message->removeListener(mMessageHandlers);// Remove old listener if already exists message->addListener(mMessageHandlers); createThumbnail(message); insertMessageAtEnd(message); message->send(); emit messageSent(message); } // ----------------------------------------------------------------------------- void ChatModel::downloadFile (int id) { const ChatEntryData entry = getFileMessageEntry(id); if (!entry.second) return; shared_ptr message = static_pointer_cast(entry.second); switch (static_cast(message->getState())) { case MessageStatusDelivered: case MessageStatusDeliveredToUser: case MessageStatusDisplayed: case MessageStatusFileTransferDone: break; default: qWarning() << QStringLiteral("Unable to download file of entry %1. It was not uploaded.").arg(id); return; } bool soFarSoGood; const QString safeFilePath = Utils::getSafeFilePath( QStringLiteral("%1%2") .arg(CoreManager::getInstance()->getSettingsModel()->getDownloadFolder()) .arg(entry.first["fileName"].toString()), &soFarSoGood ); if (!soFarSoGood) { qWarning() << QStringLiteral("Unable to create safe file path for: %1.").arg(id); return; } message->removeListener(mMessageHandlers);// Remove old listener if already exists message->addListener(mMessageHandlers); message->getContents().front()->setFilePath(Utils::appStringToCoreString(safeFilePath)); if( !message->isFileTransfer()){ QMessageBox::warning(nullptr, "Download File", "This file was already downloaded and is no more on the server. Your peer have to resend it if you want to get it"); }else { if (!message->downloadContent(message->getFileTransferInformation())) qWarning() << QStringLiteral("Unable to download file of entry %1.").arg(id); } } void ChatModel::openFile (int id, bool showDirectory) { const ChatEntryData entry = getFileMessageEntry(id); if (!entry.second) return; shared_ptr message = static_pointer_cast(entry.second); if (!entry.first["wasDownloaded"].toBool()) { downloadFile(id); }else{ QFileInfo info(getMessageAppData(message).m_path); QDesktopServices::openUrl( QUrl(QStringLiteral("file:///%1").arg(showDirectory ? info.absolutePath() : info.absoluteFilePath())) ); } } bool ChatModel::fileWasDownloaded (int id) { const ChatEntryData entry = getFileMessageEntry(id); return entry.second && ::fileWasDownloaded(static_pointer_cast(entry.second)); } void ChatModel::compose () { mChatRoom->compose(); } void ChatModel::resetMessageCount () { if (mChatRoom->getUnreadMessagesCount() > 0){ mChatRoom->markAsRead();// Marking as read is only for messages. Not for calls. } emit messageCountReset(); } // ----------------------------------------------------------------------------- const ChatModel::ChatEntryData ChatModel::getFileMessageEntry (int id) { if (id < 0 || id > mEntries.count()) { qWarning() << QStringLiteral("Entry %1 not exists.").arg(id); return ChatEntryData(); } const ChatEntryData entry = mEntries[id]; if (entry.first["type"] != EntryType::MessageEntry) { qWarning() << QStringLiteral("Unable to download entry %1. It's not a message.").arg(id); return ChatEntryData(); } shared_ptr message = static_pointer_cast(entry.second); if (!message->getFileTransferInformation()) { qWarning() << QStringLiteral("Entry %1 is not a file message.").arg(id); return ChatEntryData(); } return entry; } // ----------------------------------------------------------------------------- void ChatModel::removeEntry (ChatEntryData &entry) { int type = entry.first["type"].toInt(); switch (type) { case ChatModel::MessageEntry: { shared_ptr message = static_pointer_cast(entry.second); removeFileMessageThumbnail(message); mChatRoom->deleteMessage(message); break; } case ChatModel::CallEntry: { if (entry.first["status"].toInt() == CallStatusSuccess) { // WARNING: Unable to remove symmetric call here. (start/end) // We are between `beginRemoveRows` and `endRemoveRows`. // A solution is to schedule a `removeEntry` call in the Qt main loop. shared_ptr linphonePtr = entry.second; QTimer::singleShot(0, this, [this, linphonePtr]() { auto it = find_if(mEntries.begin(), mEntries.end(), [linphonePtr](const ChatEntryData &entry) { return entry.second == linphonePtr; }); if (it != mEntries.end()) removeEntry(int(distance(mEntries.begin(), it))); }); } CoreManager::getInstance()->getCore()->removeCallLog(static_pointer_cast(entry.second)); break; } default: qWarning() << QStringLiteral("Unknown chat entry type: %1.").arg(type); } } void ChatModel::insertCall (const shared_ptr &callLog) { linphone::Call::Status status = callLog->getStatus(); auto insertEntry = [this]( const ChatEntryData &entry, const QList::iterator *start = nullptr ) { auto it = lower_bound(start ? *start : mEntries.begin(), mEntries.end(), entry, [](const ChatEntryData &a, const ChatEntryData &b) { return a.first["timestamp"] < b.first["timestamp"]; }); int row = int(distance(mEntries.begin(), it)); beginInsertRows(QModelIndex(), row, row); it = mEntries.insert(it, entry); endInsertRows(); return it; }; // Add start call. QVariantMap start; fillCallStartEntry(start, callLog); auto it = insertEntry(qMakePair(start, static_pointer_cast(callLog))); // Add end call. (if necessary) if (status == linphone::Call::Status::Success) { QVariantMap end; fillCallEndEntry(end, callLog); insertEntry(qMakePair(end, static_pointer_cast(callLog)), &it); } } void ChatModel::insertMessageAtEnd (const shared_ptr &message) { int row = mEntries.count(); beginInsertRows(QModelIndex(), row, row); QVariantMap map{ { "type", EntryType::MessageEntry }, { "timestamp", QDateTime::fromMSecsSinceEpoch(message->getTime() * 1000) } }; fillMessageEntry(map, message); mEntries << qMakePair(map, static_pointer_cast(message)); endInsertRows(); } // ----------------------------------------------------------------------------- void ChatModel::handleCallStateChanged (const shared_ptr &call, linphone::Call::State state) { if ( (state == linphone::Call::State::End || state == linphone::Call::State::Error) && mChatRoom == CoreManager::getInstance()->getCore()->findChatRoom(call->getRemoteAddress(), mChatRoom->getLocalAddress()) ) insertCall(call->getCallLog()); } void ChatModel::handleIsComposingChanged (const shared_ptr &chatRoom) { if (mChatRoom == chatRoom) { bool isRemoteComposing = mChatRoom->isRemoteComposing(); if (isRemoteComposing != mIsRemoteComposing) { mIsRemoteComposing = isRemoteComposing; emit isRemoteComposingChanged(mIsRemoteComposing); } } } void ChatModel::handleMessageReceived (const shared_ptr &message) { if (mChatRoom == message->getChatRoom()) { insertMessageAtEnd(message); emit messageReceived(message); } } linphone-desktop-4.2.5/linphone-app/src/components/chat/ChatModel.hpp000066400000000000000000000116651376717241300256670ustar00rootroot00000000000000/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef CHAT_MODEL_H_ #define CHAT_MODEL_H_ #include #include // ============================================================================= // Fetch all N messages of a ChatRoom. // ============================================================================= class CoreHandlers; class ChatModel : public QAbstractListModel { class MessageHandlers; Q_OBJECT; public: enum Roles { ChatEntry = Qt::DisplayRole, SectionDate }; enum EntryType { GenericEntry, MessageEntry, CallEntry }; Q_ENUM(EntryType); enum CallStatus { CallStatusDeclined = int(linphone::Call::Status::Declined), CallStatusMissed = int(linphone::Call::Status::Missed), CallStatusSuccess = int(linphone::Call::Status::Success), CallStatusAborted = int(linphone::Call::Status::Aborted), CallStatusEarlyAborted = int(linphone::Call::Status::EarlyAborted), CallStatusAcceptedElsewhere = int(linphone::Call::Status::AcceptedElsewhere), CallStatusDeclinedElsewhere = int(linphone::Call::Status::DeclinedElsewhere) }; Q_ENUM(CallStatus); enum MessageStatus { MessageStatusDelivered = int(linphone::ChatMessage::State::Delivered), MessageStatusDeliveredToUser = int(linphone::ChatMessage::State::DeliveredToUser), MessageStatusDisplayed = int(linphone::ChatMessage::State::Displayed), MessageStatusFileTransferDone = int(linphone::ChatMessage::State::FileTransferDone), MessageStatusFileTransferError = int(linphone::ChatMessage::State::FileTransferError), MessageStatusFileTransferInProgress = int(linphone::ChatMessage::State::FileTransferInProgress), MessageStatusIdle = int(linphone::ChatMessage::State::Idle), MessageStatusInProgress = int(linphone::ChatMessage::State::InProgress), MessageStatusNotDelivered = int(linphone::ChatMessage::State::NotDelivered) }; Q_ENUM(MessageStatus); ChatModel (const QString &peerAddress, const QString &localAddress); ~ChatModel (); int rowCount (const QModelIndex &index = QModelIndex()) const override; QHash roleNames () const override; QVariant data (const QModelIndex &index, int role) const override; bool removeRow (int row, const QModelIndex &parent = QModelIndex()); bool removeRows (int row, int count, const QModelIndex &parent = QModelIndex()) override; QString getPeerAddress () const; QString getLocalAddress () const; QString getFullPeerAddress () const; QString getFullLocalAddress () const; bool getIsRemoteComposing () const; void removeEntry (int id); void removeAllEntries (); void sendMessage (const QString &message); void resendMessage (int id); void sendFileMessage (const QString &path); void downloadFile (int id); void openFile (int id, bool showDirectory = false); void openFileDirectory (int id) { openFile(id, true); } bool fileWasDownloaded (int id); void compose (); void resetMessageCount (); signals: bool isRemoteComposingChanged (bool status); void allEntriesRemoved (); void lastEntryRemoved (); void messageSent (const std::shared_ptr &message); void messageReceived (const std::shared_ptr &message); void messageCountReset (); void focused (); private: typedef QPair> ChatEntryData; void setSipAddresses (const QString &peerAddress, const QString &localAddress); const ChatEntryData getFileMessageEntry (int id); void removeEntry (ChatEntryData &entry); void insertCall (const std::shared_ptr &callLog); void insertMessageAtEnd (const std::shared_ptr &message); void handleCallStateChanged (const std::shared_ptr &call, linphone::Call::State state); void handleIsComposingChanged (const std::shared_ptr &chatRoom); void handleMessageReceived (const std::shared_ptr &message); bool mIsRemoteComposing = false; mutable QList mEntries; std::shared_ptr mChatRoom; std::shared_ptr mCoreHandlers; std::shared_ptr mMessageHandlers; }; #endif // CHAT_MODEL_H_ linphone-desktop-4.2.5/linphone-app/src/components/chat/ChatProxyModel.cpp000066400000000000000000000207601376717241300267200ustar00rootroot00000000000000/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include #include "app/App.hpp" #include "components/core/CoreManager.hpp" #include "ChatProxyModel.hpp" // ============================================================================= using namespace std; QString ChatProxyModel::gCachedText; // Fetch the L last filtered chat entries. class ChatProxyModel::ChatModelFilter : public QSortFilterProxyModel { public: ChatModelFilter (QObject *parent) : QSortFilterProxyModel(parent) {} ChatModel::EntryType getEntryTypeFilter () { return mEntryTypeFilter; } void setEntryTypeFilter (ChatModel::EntryType type) { mEntryTypeFilter = type; invalidate(); } protected: bool filterAcceptsRow (int sourceRow, const QModelIndex &) const override { if (mEntryTypeFilter == ChatModel::EntryType::GenericEntry) return true; QModelIndex index = sourceModel()->index(sourceRow, 0, QModelIndex()); const QVariantMap data = index.data().toMap(); return data["type"].toInt() == mEntryTypeFilter; } private: ChatModel::EntryType mEntryTypeFilter = ChatModel::EntryType::GenericEntry; }; // ============================================================================= ChatProxyModel::ChatProxyModel (QObject *parent) : QSortFilterProxyModel(parent) { setSourceModel(new ChatModelFilter(this)); App *app = App::getInstance(); QObject::connect(app->getMainWindow(), &QWindow::activeChanged, this, [this]() { handleIsActiveChanged(App::getInstance()->getMainWindow()); }); QQuickWindow *callsWindow = app->getCallsWindow(); if (callsWindow) QObject::connect(callsWindow, &QWindow::activeChanged, this, [this, callsWindow]() { handleIsActiveChanged(callsWindow); }); } // ----------------------------------------------------------------------------- #define GET_CHAT_MODEL() \ if (!mChatModel) \ return; \ mChatModel #define CREATE_PARENT_MODEL_FUNCTION(METHOD) \ void ChatProxyModel::METHOD () { \ GET_CHAT_MODEL()->METHOD(); \ } #define CREATE_PARENT_MODEL_FUNCTION_WITH_PARAM(METHOD, ARG_TYPE) \ void ChatProxyModel::METHOD (ARG_TYPE value) { \ GET_CHAT_MODEL()->METHOD(value); \ } #define CREATE_PARENT_MODEL_FUNCTION_WITH_ID(METHOD) \ void ChatProxyModel::METHOD (int id) { \ QModelIndex sourceIndex = mapToSource(index(id, 0)); \ GET_CHAT_MODEL()->METHOD( \ static_cast(sourceModel())->mapToSource(sourceIndex).row() \ ); \ } CREATE_PARENT_MODEL_FUNCTION(removeAllEntries); CREATE_PARENT_MODEL_FUNCTION_WITH_PARAM(sendFileMessage, const QString &); CREATE_PARENT_MODEL_FUNCTION_WITH_PARAM(sendMessage, const QString &); CREATE_PARENT_MODEL_FUNCTION_WITH_ID(downloadFile); CREATE_PARENT_MODEL_FUNCTION_WITH_ID(openFile); CREATE_PARENT_MODEL_FUNCTION_WITH_ID(openFileDirectory); CREATE_PARENT_MODEL_FUNCTION_WITH_ID(removeEntry); CREATE_PARENT_MODEL_FUNCTION_WITH_ID(resendMessage); #undef GET_CHAT_MODEL #undef CREATE_PARENT_MODEL_FUNCTION #undef CREATE_PARENT_MODEL_FUNCTION_WITH_PARAM #undef CREATE_PARENT_MODEL_FUNCTION_WITH_ID void ChatProxyModel::compose (const QString& text) { if (mChatModel) mChatModel->compose(); gCachedText = text; } // ----------------------------------------------------------------------------- void ChatProxyModel::loadMoreEntries () { int count = rowCount(); int parentCount = sourceModel()->rowCount(); if (count < parentCount) { // Do not increase `mMaxDisplayedEntries` if it's not necessary... // Limit qml calls. if (count == mMaxDisplayedEntries) mMaxDisplayedEntries += EntriesChunkSize; invalidateFilter(); count = rowCount() - count; if (count > 0) emit moreEntriesLoaded(count); } } void ChatProxyModel::setEntryTypeFilter (ChatModel::EntryType type) { ChatModelFilter *chatModelFilter = static_cast(sourceModel()); if (chatModelFilter->getEntryTypeFilter() != type) { chatModelFilter->setEntryTypeFilter(type); emit entryTypeFilterChanged(type); } } // ----------------------------------------------------------------------------- bool ChatProxyModel::filterAcceptsRow (int sourceRow, const QModelIndex &) const { return sourceModel()->rowCount() - sourceRow <= mMaxDisplayedEntries; } // ----------------------------------------------------------------------------- QString ChatProxyModel::getPeerAddress () const { return mChatModel ? mChatModel->getPeerAddress() : QString(""); } void ChatProxyModel::setPeerAddress (const QString &peerAddress) { mPeerAddress = peerAddress; reload(); } QString ChatProxyModel::getLocalAddress () const { return mChatModel ? mChatModel->getLocalAddress() : QString(""); } void ChatProxyModel::setLocalAddress (const QString &localAddress) { mLocalAddress = localAddress; reload(); } QString ChatProxyModel::getFullPeerAddress () const { return mChatModel ? mChatModel->getFullPeerAddress() : QString(""); } void ChatProxyModel::setFullPeerAddress (const QString &peerAddress) { mFullPeerAddress = peerAddress; //reload(); } QString ChatProxyModel::getFullLocalAddress () const { return mChatModel ? mChatModel->getFullLocalAddress() : QString(""); } void ChatProxyModel::setFullLocalAddress (const QString &localAddress) { mFullLocalAddress = localAddress; //reload(); } bool ChatProxyModel::getIsRemoteComposing () const { return mChatModel ? mChatModel->getIsRemoteComposing() : false; } QString ChatProxyModel::getCachedText() const{ return gCachedText; } // ----------------------------------------------------------------------------- void ChatProxyModel::reload () { mMaxDisplayedEntries = EntriesChunkSize; if (mChatModel) { ChatModel *chatModel = mChatModel.get(); QObject::disconnect(chatModel, &ChatModel::isRemoteComposingChanged, this, &ChatProxyModel::handleIsRemoteComposingChanged); QObject::disconnect(chatModel, &ChatModel::messageReceived, this, &ChatProxyModel::handleMessageReceived); QObject::disconnect(chatModel, &ChatModel::messageSent, this, &ChatProxyModel::handleMessageSent); } mChatModel = CoreManager::getInstance()->getChatModel(mPeerAddress, mLocalAddress); if (mChatModel) { ChatModel *chatModel = mChatModel.get(); QObject::connect(chatModel, &ChatModel::isRemoteComposingChanged, this, &ChatProxyModel::handleIsRemoteComposingChanged); QObject::connect(chatModel, &ChatModel::messageReceived, this, &ChatProxyModel::handleMessageReceived); QObject::connect(chatModel, &ChatModel::messageSent, this, &ChatProxyModel::handleMessageSent); } static_cast(sourceModel())->setSourceModel(mChatModel.get()); } void ChatProxyModel::resetMessageCount(){ if( mChatModel){ mChatModel->resetMessageCount(); } } // ----------------------------------------------------------------------------- static inline QWindow *getParentWindow (QObject *object) { App *app = App::getInstance(); const QWindow *mainWindow = app->getMainWindow(); const QWindow *callsWindow = app->getCallsWindow(); for (QObject *parent = object->parent(); parent; parent = parent->parent()) if (parent == mainWindow || parent == callsWindow) return static_cast(parent); return nullptr; } void ChatProxyModel::handleIsActiveChanged (QWindow *window) { if (mChatModel && window->isActive() && getParentWindow(this) == window) { mChatModel->resetMessageCount(); mChatModel->focused(); } } void ChatProxyModel::handleIsRemoteComposingChanged (bool status) { emit isRemoteComposingChanged(status); } void ChatProxyModel::handleMessageReceived (const shared_ptr &) { mMaxDisplayedEntries++; QWindow *window = getParentWindow(this); if (window && window->isActive()) mChatModel->resetMessageCount(); } void ChatProxyModel::handleMessageSent (const shared_ptr &) { mMaxDisplayedEntries++; } linphone-desktop-4.2.5/linphone-app/src/components/chat/ChatProxyModel.hpp000066400000000000000000000074501376717241300267260ustar00rootroot00000000000000/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef CHAT_PROXY_MODEL_H_ #define CHAT_PROXY_MODEL_H_ #include #include "ChatModel.hpp" // ============================================================================= class QWindow; class ChatProxyModel : public QSortFilterProxyModel { class ChatModelFilter; Q_OBJECT; Q_PROPERTY(QString peerAddress READ getPeerAddress WRITE setPeerAddress NOTIFY peerAddressChanged); Q_PROPERTY(QString localAddress READ getLocalAddress WRITE setLocalAddress NOTIFY localAddressChanged); Q_PROPERTY(QString fullPeerAddress READ getFullPeerAddress WRITE setFullPeerAddress NOTIFY fullPeerAddressChanged); Q_PROPERTY(QString fullLocalAddress READ getFullLocalAddress WRITE setFullLocalAddress NOTIFY fullLocalAddressChanged); Q_PROPERTY(bool isRemoteComposing READ getIsRemoteComposing NOTIFY isRemoteComposingChanged); Q_PROPERTY(QString cachedText READ getCachedText); public: ChatProxyModel (QObject *parent = Q_NULLPTR); Q_INVOKABLE void loadMoreEntries (); Q_INVOKABLE void setEntryTypeFilter (ChatModel::EntryType type); Q_INVOKABLE void removeEntry (int id); Q_INVOKABLE void removeAllEntries (); Q_INVOKABLE void sendMessage (const QString &message); Q_INVOKABLE void resendMessage (int id); Q_INVOKABLE void sendFileMessage (const QString &path); Q_INVOKABLE void downloadFile (int id); Q_INVOKABLE void openFile (int id); Q_INVOKABLE void openFileDirectory (int id); Q_INVOKABLE void compose (const QString& text); Q_INVOKABLE void resetMessageCount(); signals: void peerAddressChanged (const QString &peerAddress); void localAddressChanged (const QString &localAddress); void fullPeerAddressChanged (const QString &fullPeerAddress); void fullLocalAddressChanged (const QString &fullLocalAddress); bool isRemoteComposingChanged (bool status); void moreEntriesLoaded (int n); void entryTypeFilterChanged (ChatModel::EntryType type); protected: bool filterAcceptsRow (int sourceRow, const QModelIndex &sourceParent) const override; private: QString getPeerAddress () const; void setPeerAddress (const QString &peerAddress); QString getLocalAddress () const; void setLocalAddress (const QString &localAddress); QString getFullPeerAddress () const; void setFullPeerAddress (const QString &peerAddress); QString getFullLocalAddress () const; void setFullLocalAddress (const QString &localAddress); bool getIsRemoteComposing () const; QString getCachedText() const; void reload (); void handleIsActiveChanged (QWindow *window); void handleIsRemoteComposingChanged (bool status); void handleMessageReceived (const std::shared_ptr &message); void handleMessageSent (const std::shared_ptr &message); int mMaxDisplayedEntries = EntriesChunkSize; QString mPeerAddress; QString mLocalAddress; QString mFullPeerAddress; QString mFullLocalAddress; static QString gCachedText; std::shared_ptr mChatModel; static constexpr int EntriesChunkSize = 50; }; #endif // CHAT_PROXY_MODEL_H_ linphone-desktop-4.2.5/linphone-app/src/components/codecs/000077500000000000000000000000001376717241300236265ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/src/components/codecs/AbstractCodecsModel.cpp000066400000000000000000000140621376717241300302020ustar00rootroot00000000000000/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "app/paths/Paths.hpp" #include "components/core/CoreManager.hpp" #include "utils/Utils.hpp" #include "AbstractCodecsModel.hpp" // ============================================================================= using namespace std; static inline shared_ptr getCodecFromMap (const QVariantMap &map) { return map.value("__codec").value>(); } // ----------------------------------------------------------------------------- AbstractCodecsModel::AbstractCodecsModel (QObject *parent) : QAbstractListModel(parent) {} int AbstractCodecsModel::rowCount (const QModelIndex &) const { return mCodecs.count(); } QHash AbstractCodecsModel::roleNames () const { QHash roles; roles[Qt::DisplayRole] = "$codec"; return roles; } QVariant AbstractCodecsModel::data (const QModelIndex &index, int role) const { int row = index.row(); if (!index.isValid() || row < 0 || row >= mCodecs.count()) return QVariant(); if (role == Qt::DisplayRole) return mCodecs[row]; return QVariant(); } // ----------------------------------------------------------------------------- void AbstractCodecsModel::enableCodec (int id, bool status) { Q_ASSERT(id >= 0 && id < mCodecs.count()); QVariantMap &map = mCodecs[id]; shared_ptr codec = getCodecFromMap(map); if (codec) { codec->enable(status); map["enabled"] = codec->enabled(); emit dataChanged(index(id, 0), index(id, 0)); } } void AbstractCodecsModel::moveCodec (int source, int destination) { moveRow(QModelIndex(), source, QModelIndex(), destination); } void AbstractCodecsModel::setBitrate (int id, int bitrate) { Q_ASSERT(id >= 0 && id < mCodecs.count()); QVariantMap &map = mCodecs[id]; shared_ptr codec = getCodecFromMap(map); if (codec) { codec->setNormalBitrate(bitrate); map["bitrate"] = codec->getNormalBitrate(); emit dataChanged(index(id, 0), index(id, 0)); } } void AbstractCodecsModel::setRecvFmtp (int id, const QString &recvFmtp) { Q_ASSERT(id >= 0 && id < mCodecs.count()); QVariantMap &map = mCodecs[id]; shared_ptr codec = getCodecFromMap(map); if (codec) { codec->setRecvFmtp(Utils::appStringToCoreString(recvFmtp)); map["recvFmtp"] = Utils::coreStringToAppString(codec->getRecvFmtp()); emit dataChanged(index(id, 0), index(id, 0)); } } // ----------------------------------------------------------------------------- bool AbstractCodecsModel::moveRows ( const QModelIndex &sourceParent, int sourceRow, int count, const QModelIndex &destinationParent, int destinationChild ) { // TODO: Do not move downloadable codecs. int limit = sourceRow + count - 1; { int nCodecs = mCodecs.count(); if ( sourceRow < 0 || destinationChild < 0 || count < 0 || destinationChild > nCodecs || limit >= nCodecs || (sourceRow <= destinationChild && sourceRow + count >= destinationChild) ) return false; } beginMoveRows(sourceParent, sourceRow, limit, destinationParent, destinationChild); // Update UI. if (destinationChild > sourceRow) { --destinationChild; for (int i = sourceRow; i <= limit; ++i) { mCodecs.move(sourceRow, destinationChild + i - sourceRow); } } else { for (int i = sourceRow; i <= limit; ++i) mCodecs.move(sourceRow + i - sourceRow, destinationChild + i - sourceRow); } // Update linphone codecs list. list> codecs; for (const auto &map : mCodecs) { // Do not update downloadable codecs. shared_ptr codec = getCodecFromMap(map); if (codec) codecs.push_back(codec); } updateCodecs(codecs); endMoveRows(); return true; } // ----------------------------------------------------------------------------- void AbstractCodecsModel::addCodec (shared_ptr &codec) { QVariantMap map; map["bitrate"] = codec->getNormalBitrate(); map["channels"] = codec->getChannels(); map["clockRate"] = codec->getClockRate(); map["description"] = Utils::coreStringToAppString(codec->getDescription()); map["enabled"] = codec->enabled(); map["encoderDescription"] = Utils::coreStringToAppString(codec->getEncoderDescription()); map["isUsable"] = codec->isUsable(); // TODO: Notify in UI when unusable. map["isVbr"] = codec->isVbr(); map["mime"] = Utils::coreStringToAppString(codec->getMimeType()); map["number"] = codec->getNumber(); map["recvFmtp"] = Utils::coreStringToAppString(codec->getRecvFmtp()); map["__codec"] = QVariant::fromValue(codec); mCodecs << map; } void AbstractCodecsModel::addDownloadableCodec ( const QString &mime, const QString &encoderDescription, const QString &downloadUrl, const QString &installName ) { QVariantMap map; map["downloadUrl"] = downloadUrl; map["encoderDescription"] = encoderDescription; map["installName"] = installName; map["mime"] = mime; mCodecs << map; } QVariantMap AbstractCodecsModel::getCodecInfo (const QString &mime) const { for (const auto &codec : mCodecs) if (codec.value("mime") == mime) return codec; return QVariantMap(); }; QString AbstractCodecsModel::getCodecsFolder () { return Utils::coreStringToAppString(Paths::getCodecsDirPath()); } linphone-desktop-4.2.5/linphone-app/src/components/codecs/AbstractCodecsModel.hpp000066400000000000000000000046471376717241300302170ustar00rootroot00000000000000/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef ABSTRACT_CODECS_MODEL_H_ #define ABSTRACT_CODECS_MODEL_H_ #include #include // ============================================================================= namespace linphone { class PayloadType; } class AbstractCodecsModel : public QAbstractListModel { Q_OBJECT; Q_PROPERTY(QString codecsFolder READ getCodecsFolder CONSTANT); public: AbstractCodecsModel (QObject *parent = Q_NULLPTR); int rowCount (const QModelIndex &index = QModelIndex()) const override; QHash roleNames () const override; QVariant data (const QModelIndex &index, int role = Qt::DisplayRole) const override; Q_INVOKABLE void enableCodec (int id, bool status); Q_INVOKABLE void moveCodec (int source, int destination); Q_INVOKABLE void setBitrate (int id, int bitrate); Q_INVOKABLE void setRecvFmtp (int id, const QString &recvFmtp); Q_INVOKABLE virtual void reload () {}; Q_INVOKABLE QVariantMap getCodecInfo (const QString &mime) const; protected: bool moveRows ( const QModelIndex &sourceParent, int sourceRow, int count, const QModelIndex &destinationParent, int destinationChild ) override; void addCodec (std::shared_ptr &codec); void addDownloadableCodec ( const QString &mime, const QString &encoderDescription, const QString &downloadUrl, const QString &installName ); virtual void updateCodecs (std::list> &codecs) = 0; static QString getCodecsFolder (); QList mCodecs; }; Q_DECLARE_METATYPE(std::shared_ptr); #endif // ABSTRACT_CODECS_MODEL_H_ linphone-desktop-4.2.5/linphone-app/src/components/codecs/AudioCodecsModel.cpp000066400000000000000000000024611376717241300275000ustar00rootroot00000000000000/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "components/core/CoreManager.hpp" #include "AudioCodecsModel.hpp" // ============================================================================= using namespace std; AudioCodecsModel::AudioCodecsModel (QObject *parent) : AbstractCodecsModel(parent) { for (auto &codec : CoreManager::getInstance()->getCore()->getAudioPayloadTypes()) addCodec(codec); } void AudioCodecsModel::updateCodecs (list> &codecs) { CoreManager::getInstance()->getCore()->setAudioPayloadTypes(codecs); } linphone-desktop-4.2.5/linphone-app/src/components/codecs/AudioCodecsModel.hpp000066400000000000000000000023221376717241300275010ustar00rootroot00000000000000/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef AUDIO_CODECS_MODEL_H_ #define AUDIO_CODECS_MODEL_H_ #include "AbstractCodecsModel.hpp" // ============================================================================= class AudioCodecsModel : public AbstractCodecsModel { Q_OBJECT; public: AudioCodecsModel (QObject *parent = Q_NULLPTR); private: void updateCodecs (std::list> &codecs) override; }; #endif // AUDIO_CODECS_MODEL_H_ linphone-desktop-4.2.5/linphone-app/src/components/codecs/VideoCodecsModel.cpp000066400000000000000000000160371376717241300275110ustar00rootroot00000000000000/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include #include #include #include "app/paths/Paths.hpp" #include "components/core/CoreManager.hpp" #include "components/file/FileDownloader.hpp" #include "components/file/FileExtractor.hpp" #include "utils/Utils.hpp" #include "VideoCodecsModel.hpp" #include // ============================================================================= using namespace std; namespace { #if defined(Q_OS_LINUX) || defined(Q_OS_WIN) constexpr char H264Description[] = "Provided by CISCO SYSTEM,INC"; #endif // if defined(Q_OS_LINUX) || defined(Q_OS_WIN) #ifdef Q_OS_LINUX constexpr char LibraryExtension[] = "so"; constexpr char H264InstallName[] = "libopenh264.so"; #ifdef Q_PROCESSOR_X86_64 constexpr char PluginUrlH264[] = "http://ciscobinary.openh264.org/libopenh264-2.1.0-linux64.5.so.bz2"; #else constexpr char PluginUrlH264[] = "http://ciscobinary.openh264.org/libopenh264-2.1-0-linux32.5.so.bz2"; #endif // ifdef Q_PROCESSOR_X86_64 #elif defined(Q_OS_WIN) constexpr char LibraryExtension[] = "dll"; constexpr char H264InstallName[] = "openh264.dll"; #ifdef Q_OS_WIN64 constexpr char PluginUrlH264[] = "http://ciscobinary.openh264.org/openh264-2.1.0-win64.dll.bz2"; #else constexpr char PluginUrlH264[] = "http://ciscobinary.openh264.org/openh264-2.1.0-win32.dll.bz2"; #endif // ifdef Q_OS_WIN64 #endif // ifdef Q_OS_LINUX } VideoCodecsModel::VideoCodecsModel (QObject *parent) : AbstractCodecsModel(parent) { load(); } #if defined(Q_OS_LINUX) || defined(Q_OS_WIN) static bool downloadUpdatableCodec ( QObject *parent, const QString &codecsFolder, const QString &mime, const QString &downloadUrl, const QString &installName ) { QString versionFilePath = codecsFolder + mime + ".txt"; QFile versionFile(versionFilePath); if (!versionFile.exists() && !QFileInfo::exists(codecsFolder + installName)) return false; // Must be downloaded one time before. if (!versionFile.open(QIODevice::ReadOnly)) qWarning() << QStringLiteral("Unable to read codec version from: `%1`.").arg(versionFilePath); else if (!QString::compare(QTextStream(&versionFile).readAll(), downloadUrl, Qt::CaseInsensitive)) return false; qInfo() << QStringLiteral("Updating `%1` codec...").arg(mime); FileDownloader *fileDownloader = new FileDownloader(parent); fileDownloader->setUrl(QUrl(downloadUrl)); fileDownloader->setDownloadFolder(codecsFolder); FileExtractor *fileExtractor = new FileExtractor(fileDownloader); fileExtractor->setExtractFolder(codecsFolder); fileExtractor->setExtractName(installName + ".in"); QObject::connect(fileDownloader, &FileDownloader::downloadFinished, [fileExtractor](const QString &filePath) { fileExtractor->setFile(filePath); fileExtractor->extract(); }); QObject::connect(fileDownloader, &FileDownloader::downloadFailed, [fileDownloader]() { fileDownloader->deleteLater(); }); QObject::connect(fileExtractor, &FileExtractor::extractFinished, [fileDownloader, fileExtractor, versionFilePath, downloadUrl]() { QFile versionFile(versionFilePath); if (!versionFile.open(QIODevice::WriteOnly)) { qWarning() << QStringLiteral("Unable to write codec version in: `%1`.").arg(versionFilePath); return; } if (versionFile.write(Utils::appStringToCoreString(downloadUrl).c_str(), downloadUrl.length()) == -1) { fileExtractor->remove(); versionFile.close(); versionFile.remove(); } fileDownloader->remove(); fileDownloader->deleteLater(); }); QObject::connect(fileExtractor, &FileExtractor::extractFailed, [fileDownloader]() { fileDownloader->remove(); fileDownloader->deleteLater(); }); fileDownloader->download(); return true; } #endif // if defined(Q_OS_LINUX) || defined(Q_OS_WIN) void VideoCodecsModel::updateCodecs () { #if defined(Q_OS_LINUX) || defined(Q_OS_WIN) static const QString codecSuffix = QStringLiteral(".%1").arg(LibraryExtension); QDirIterator it(getCodecsFolder()); while (it.hasNext()) { QFileInfo info(it.next()); if (info.suffix() == QLatin1String("in")) { QString codecName = info.completeBaseName(); if (codecName.endsWith(codecSuffix)) { QString codecPath = info.dir().path() + QDir::separator() + codecName; QFile::remove(codecPath); QFile::rename(info.filePath(), codecPath); } } } #endif // if defined(Q_OS_LINUX) || defined(Q_OS_WIN) } void VideoCodecsModel::downloadUpdatableCodecs (QObject *parent) { #if defined(Q_OS_LINUX) || defined(Q_OS_WIN) downloadUpdatableCodec(parent, getCodecsFolder(), "H264", PluginUrlH264, H264InstallName); #else Q_UNUSED(parent); #endif // if defined(Q_OS_LINUX) || defined(Q_OS_WIN) } void VideoCodecsModel::updateCodecs (list> &codecs) { CoreManager::getInstance()->getCore()->setVideoPayloadTypes(codecs); } void VideoCodecsModel::load () { mCodecs.clear(); shared_ptr core = CoreManager::getInstance()->getCore(); // Load downloaded codecs like OpenH264. #if defined(Q_OS_LINUX) || defined(Q_OS_WIN) QDirIterator it(getCodecsFolder()); while (it.hasNext()) { QFileInfo info(it.next()); const QString filename(info.fileName()); if ( QLibrary::isLibrary(filename) ) { qInfo() << QStringLiteral("Loading `%1` symbols...").arg(filename); if (!QLibrary(info.filePath()).load()) //lib.load()) qWarning() << QStringLiteral("Failed to load `%1` symbols.").arg(filename); } } core->reloadMsPlugins(""); #endif // if defined(Q_OS_LINUX) || defined(Q_OS_WIN) // Add codecs. auto codecs = core->getVideoPayloadTypes(); for (auto &codec : codecs) addCodec(codec); // Add downloadable codecs. // TODO: Add an API to check if the ms h264 plugin is available. #if defined(Q_OS_LINUX) || defined(Q_OS_WIN) if (find_if(codecs.begin(), codecs.end(), [](const shared_ptr &codec) { return codec->getMimeType() == "H264"; }) == codecs.end()) addDownloadableCodec("H264", H264Description, PluginUrlH264, H264InstallName); #endif // if defined(Q_OS_LINUX) || defined(Q_OS_WIN) } void VideoCodecsModel::reload () { beginResetModel(); load(); endResetModel(); } linphone-desktop-4.2.5/linphone-app/src/components/codecs/VideoCodecsModel.hpp000066400000000000000000000025271376717241300275150ustar00rootroot00000000000000/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef VIDEO_CODECS_MODEL_H_ #define VIDEO_CODECS_MODEL_H_ #include "AbstractCodecsModel.hpp" // ============================================================================= class VideoCodecsModel : public AbstractCodecsModel { Q_OBJECT; public: VideoCodecsModel (QObject *parent = Q_NULLPTR); static void updateCodecs (); static void downloadUpdatableCodecs (QObject *parent); private: void updateCodecs (std::list> &codecs) override; void load (); void reload () override; }; #endif // VIDEO_CODECS_MODEL_H_ linphone-desktop-4.2.5/linphone-app/src/components/conference/000077500000000000000000000000001376717241300244755ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/src/components/conference/ConferenceAddModel.cpp000066400000000000000000000163051376717241300306470ustar00rootroot00000000000000/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include #include "components/core/CoreManager.hpp" #include "components/sip-addresses/SipAddressesModel.hpp" #include "utils/Utils.hpp" #include "ConferenceAddModel.hpp" // ============================================================================= using namespace std; ConferenceHelperModel::ConferenceAddModel::ConferenceAddModel (QObject *parent) : QAbstractListModel(parent) { mConferenceHelperModel = qobject_cast(parent); Q_CHECK_PTR(mConferenceHelperModel); CoreManager *coreManager = CoreManager::getInstance(); QObject::connect( coreManager->getSipAddressesModel(), &SipAddressesModel::dataChanged, this, &ConferenceAddModel::handleDataChanged ); for (const auto &call : coreManager->getCore()->getCalls()) { if (call->getCurrentParams()->getLocalConferenceMode()) addToConference(call->getRemoteAddress()); } } int ConferenceHelperModel::ConferenceAddModel::rowCount (const QModelIndex &) const { return mRefs.count(); } QHash ConferenceHelperModel::ConferenceAddModel::roleNames () const { QHash roles; roles[Qt::DisplayRole] = "$sipAddress"; return roles; } QVariant ConferenceHelperModel::ConferenceAddModel::data (const QModelIndex &index, int role) const { int row = index.row(); if (!index.isValid() || row < 0 || row >= mRefs.count()) return QVariant(); if (role == Qt::DisplayRole) return QVariant::fromValue(*mRefs[row]); return QVariant(); } // ----------------------------------------------------------------------------- bool ConferenceHelperModel::ConferenceAddModel::addToConference (const shared_ptr &linphoneAddress) { const QString sipAddress = Utils::coreStringToAppString(linphoneAddress->asStringUriOnly()); if (mSipAddresses.contains(sipAddress)) return false; int row = rowCount(); beginInsertRows(QModelIndex(), row, row); addToConferencePrivate(linphoneAddress->clone()); endInsertRows(); mConferenceHelperModel->invalidate(); return true; } bool ConferenceHelperModel::ConferenceAddModel::addToConference (const QString &sipAddress) { if (mSipAddresses.contains(sipAddress)) return false; shared_ptr address = CoreManager::getInstance()->getCore()->interpretUrl( Utils::appStringToCoreString(sipAddress) ); if (!address) return false; int row = rowCount(); beginInsertRows(QModelIndex(), row, row); qInfo() << QStringLiteral("Add sip address to conference: `%1`.").arg(sipAddress); addToConferencePrivate(address); endInsertRows(); mConferenceHelperModel->invalidate(); return true; } bool ConferenceHelperModel::ConferenceAddModel::removeFromConference (const QString &sipAddress) { auto it = mSipAddresses.find(sipAddress); if (it == mSipAddresses.end()) return false; int row = mRefs.indexOf(&(*it)); beginRemoveRows(QModelIndex(), row, row); qInfo() << QStringLiteral("Remove sip address from conference: `%1`.").arg(sipAddress); mRefs.removeAt(row); mSipAddresses.remove(sipAddress); endRemoveRows(); mConferenceHelperModel->invalidate(); return true; } // ----------------------------------------------------------------------------- void ConferenceHelperModel::ConferenceAddModel::update () { shared_ptr conference = mConferenceHelperModel->mCore->getConference(); if(!conference){ auto parameters = mConferenceHelperModel->mCore->createConferenceParams(); parameters->enableVideo(false);// Video is not yet fully supported by the application in conference conference = mConferenceHelperModel->mCore->createConferenceWithParams(parameters); } auto currentCalls = CoreManager::getInstance()->getCore()->getCalls(); list> allLinphoneAddresses; //1) Invite participants first to avoid removing conference if empty for (const auto &map : mRefs) { shared_ptr linphoneAddress = map->value("__linphoneAddress").value>(); Q_CHECK_PTR(linphoneAddress); allLinphoneAddresses.push_back(linphoneAddress); } if( allLinphoneAddresses.size() > 0){ auto parameters = CoreManager::getInstance()->getCore()->createCallParams(nullptr); parameters->enableVideo(false); conference->inviteParticipants( allLinphoneAddresses, parameters ); } // 2) Put in pause and remove all calls that are not in the conference list for(const auto &call : CoreManager::getInstance()->getCore()->getCalls()){ const std::string callAddress = call->getRemoteAddress()->asStringUriOnly(); auto address = allLinphoneAddresses.begin(); while(address != allLinphoneAddresses.end() && (*address)->asStringUriOnly() != callAddress) ++address; if(address == allLinphoneAddresses.end()){// Not in conference list : put in pause and remove it from conference if it's the case if( call->getParams()->getLocalConferenceMode() ){// Remove conference if it is not yet requested CoreManager::getInstance()->getCore()->removeFromConference(call); }else call->pause(); } } } // ----------------------------------------------------------------------------- void ConferenceHelperModel::ConferenceAddModel::addToConferencePrivate (const shared_ptr &linphoneAddress) { QString sipAddress = Utils::coreStringToAppString(linphoneAddress->asStringUriOnly()); QVariantMap map = CoreManager::getInstance()->getSipAddressesModel()->find(sipAddress); map["sipAddress"] = sipAddress; map["__linphoneAddress"] = QVariant::fromValue(linphoneAddress); mSipAddresses[sipAddress] = map; mRefs << &mSipAddresses[sipAddress]; } // ----------------------------------------------------------------------------- void ConferenceHelperModel::ConferenceAddModel::handleDataChanged ( const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector & ) { SipAddressesModel *sipAddressesModel = CoreManager::getInstance()->getSipAddressesModel(); int limit = bottomRight.row(); for (int row = topLeft.row(); row <= limit; ++row) { const QVariantMap map = sipAddressesModel->data(sipAddressesModel->index(row, 0)).toMap(); auto it = mSipAddresses.find(map["sipAddress"].toString()); if (it != mSipAddresses.end()) { (*it)["contact"] = map.value("contact"); int row = mRefs.indexOf(&(*it)); Q_ASSERT(row != -1); emit dataChanged(index(row, 0), index(row, 0)); } } } linphone-desktop-4.2.5/linphone-app/src/components/conference/ConferenceAddModel.hpp000066400000000000000000000044671376717241300306620ustar00rootroot00000000000000/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef CONFERENCE_ADD_MODEL_H_ #define CONFERENCE_ADD_MODEL_H_ #include "ConferenceHelperModel.hpp" // ============================================================================= // Sip addresses list to add to conference. // ============================================================================= namespace linphone { class Address; } class ConferenceHelperModel::ConferenceAddModel : public QAbstractListModel { Q_OBJECT; public: ConferenceAddModel (QObject *parent = Q_NULLPTR); int rowCount (const QModelIndex &index = QModelIndex()) const override; QHash roleNames () const override; QVariant data (const QModelIndex &index, int role = Qt::DisplayRole) const override; bool addToConference (const std::shared_ptr &linphoneAddress); Q_INVOKABLE bool addToConference (const QString &sipAddress); Q_INVOKABLE bool removeFromConference (const QString &sipAddress); Q_INVOKABLE void update (); bool contains (const QString &sipAddress) const { return mSipAddresses.contains(sipAddress); } private: void addToConferencePrivate (const std::shared_ptr &linphoneAddress); void handleDataChanged ( const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector &roles = QVector() ); QHash mSipAddresses; QList mRefs; ConferenceHelperModel *mConferenceHelperModel = nullptr; }; Q_DECLARE_METATYPE(std::shared_ptr); #endif // CONFERENCE_ADD_MODEL_H_ linphone-desktop-4.2.5/linphone-app/src/components/conference/ConferenceHelperModel.cpp000066400000000000000000000057231376717241300314000ustar00rootroot00000000000000/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include #include "app/App.hpp" #include "components/calls/CallsListModel.hpp" #include "components/core/CoreManager.hpp" #include "components/sip-addresses/SipAddressesProxyModel.hpp" #include "utils/Utils.hpp" #include "ConferenceAddModel.hpp" #include "ConferenceHelperModel.hpp" // ============================================================================= using namespace std; ConferenceHelperModel::ConferenceHelperModel (QObject *parent) : QSortFilterProxyModel(parent) { mCore = CoreManager::getInstance()->getCore(); mConferenceAddModel = new ConferenceAddModel(this); App::getInstance()->getEngine()->setObjectOwnership(mConferenceAddModel, QQmlEngine::CppOwnership); QObject::connect(this, &CallsListModel::rowsRemoved, [this] { invalidate(); }); QObject::connect(this, &CallsListModel::rowsInserted, [this] { invalidate(); }); setSourceModel(new SipAddressesProxyModel(this)); sort(0); } QHash ConferenceHelperModel::roleNames () const { QHash roles; roles[Qt::DisplayRole] = "$sipAddress"; return roles; } // ----------------------------------------------------------------------------- void ConferenceHelperModel::setFilter (const QString &pattern) { static_cast(sourceModel())->setFilter(pattern); } // ----------------------------------------------------------------------------- bool ConferenceHelperModel::filterAcceptsRow (int sourceRow, const QModelIndex &sourceParent) const { const QModelIndex index = sourceModel()->index(sourceRow, 0, sourceParent); const QVariantMap data = index.data().toMap(); return !mConferenceAddModel->contains(data["sipAddress"].toString()); } // ----------------------------------------------------------------------------- bool ConferenceHelperModel::lessThan (const QModelIndex &left, const QModelIndex &right) const { shared_ptr callA = mCore->findCallFromUri( Utils::appStringToCoreString(left.data().toMap()["sipAddress"].toString()) ); shared_ptr callB = mCore->findCallFromUri( Utils::appStringToCoreString(right.data().toMap()["sipAddress"].toString()) ); return callA && !callB; } linphone-desktop-4.2.5/linphone-app/src/components/conference/ConferenceHelperModel.hpp000066400000000000000000000037731376717241300314100ustar00rootroot00000000000000/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef CONFERENCE_HELPER_MODEL_H_ #define CONFERENCE_HELPER_MODEL_H_ #include #include // ============================================================================= // Sip addresses not in conference. // Can filter the sip addresses with a pattern. // ============================================================================= namespace linphone { class Conference; class Core; } class CallModel; class ConferenceHelperModel : public QSortFilterProxyModel { Q_OBJECT; Q_PROPERTY(ConferenceHelperModel::ConferenceAddModel *toAdd READ getConferenceAddModel CONSTANT); public: class ConferenceAddModel; ConferenceHelperModel (QObject *parent = Q_NULLPTR); QHash roleNames () const override; ConferenceAddModel *getConferenceAddModel () const { return mConferenceAddModel; } Q_INVOKABLE void setFilter (const QString &pattern); protected: bool filterAcceptsRow (int sourceRow, const QModelIndex &sourceParent) const override; bool lessThan (const QModelIndex &left, const QModelIndex &right) const override; private: ConferenceAddModel *mConferenceAddModel = nullptr; std::shared_ptr mCore; }; #endif // CONFERENCE_HELPER_MODEL_H_ linphone-desktop-4.2.5/linphone-app/src/components/conference/ConferenceModel.cpp000066400000000000000000000115161376717241300302350ustar00rootroot00000000000000/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include #include #include "components/call/CallModel.hpp" #include "components/calls/CallsListModel.hpp" #include "components/core/CoreHandlers.hpp" #include "components/core/CoreManager.hpp" #include "components/settings/SettingsModel.hpp" #include "utils/LinphoneUtils.hpp" #include "utils/MediastreamerUtils.hpp" #include "utils/Utils.hpp" #include "ConferenceModel.hpp" // ============================================================================= using namespace std; ConferenceModel::ConferenceModel (QObject *parent) : QSortFilterProxyModel(parent) { QObject::connect(this, &ConferenceModel::rowsRemoved, [this] { // Warning : called before model remove its items emit countChanged(rowCount()); }); QObject::connect(this, &ConferenceModel::rowsInserted, [this] { emit countChanged(rowCount()); }); setSourceModel(CoreManager::getInstance()->getCallsListModel()); emit conferenceChanged(); QObject::connect( CoreManager::getInstance()->getHandlers().get(), &CoreHandlers::callStateChanged, this, [this] { emit conferenceChanged(); }); } // Show all paraticpants thar should be, will be or are still in conference bool ConferenceModel::filterAcceptsRow (int sourceRow, const QModelIndex &sourceParent) const { const QModelIndex index = sourceModel()->index(sourceRow, 0, sourceParent); const CallModel *callModel = index.data().value(); return callModel->getCall()->getParams()->getLocalConferenceMode() || callModel->getCall()->getCurrentParams()->getLocalConferenceMode(); } // ----------------------------------------------------------------------------- void ConferenceModel::terminate () { shared_ptr core = CoreManager::getInstance()->getCore(); core->terminateConference(); for (const auto &call : core->getCalls()) { if (call->getParams()->getLocalConferenceMode())// Terminate all call where participants are or will be in conference call->terminate(); } } // ----------------------------------------------------------------------------- void ConferenceModel::startRecording () { if (mRecording) return; qInfo() << QStringLiteral("Start recording conference:") << this; CoreManager *coreManager = CoreManager::getInstance(); coreManager->getCore()->startConferenceRecording( Utils::appStringToCoreString( QStringLiteral("%1%2.mkv") .arg(coreManager->getSettingsModel()->getSavedCallsFolder()) .arg(QDateTime::currentDateTime().toString("yyyy-MM-dd_hh-mm-ss")) ) ); mRecording = true; emit recordingChanged(true); } void ConferenceModel::stopRecording () { if (!mRecording) return; qInfo() << QStringLiteral("Stop recording conference:") << this; mRecording = false; CoreManager::getInstance()->getCore()->stopConferenceRecording(); emit recordingChanged(false); } // ----------------------------------------------------------------------------- bool ConferenceModel::getMicroMuted () const { return !CoreManager::getInstance()->getCore()->micEnabled(); } void ConferenceModel::setMicroMuted (bool status) { shared_ptr core = CoreManager::getInstance()->getCore(); if (status == core->micEnabled()) { core->enableMic(!status); emit microMutedChanged(status); } } // ----------------------------------------------------------------------------- bool ConferenceModel::getRecording () const { return mRecording; } // ----------------------------------------------------------------------------- float ConferenceModel::getMicroVu () const { return MediastreamerUtils::computeVu( CoreManager::getInstance()->getCore()->getConferenceLocalInputVolume() ); } // ----------------------------------------------------------------------------- void ConferenceModel::leave () { CoreManager::getInstance()->getCore()->leaveConference(); emit conferenceChanged(); } void ConferenceModel::join () { CoreManager::getInstance()->getCore()->enterConference(); emit conferenceChanged(); } bool ConferenceModel::isInConference () const { return CoreManager::getInstance()->getCore()->isInConference(); } linphone-desktop-4.2.5/linphone-app/src/components/conference/ConferenceModel.hpp000066400000000000000000000041761376717241300302460ustar00rootroot00000000000000/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef CONFERENCE_MODEL_H_ #define CONFERENCE_MODEL_H_ #include // ============================================================================= class CallModel; class ConferenceModel : public QSortFilterProxyModel { Q_OBJECT; Q_PROPERTY(int count READ getCount NOTIFY countChanged); Q_PROPERTY(bool microMuted READ getMicroMuted WRITE setMicroMuted NOTIFY microMutedChanged); Q_PROPERTY(float microVu READ getMicroVu CONSTANT); Q_PROPERTY(bool recording READ getRecording NOTIFY recordingChanged); Q_PROPERTY(bool isInConf READ isInConference NOTIFY conferenceChanged); public: ConferenceModel (QObject *parent = Q_NULLPTR); protected: bool filterAcceptsRow (int sourceRow, const QModelIndex &sourceParent) const override; Q_INVOKABLE void terminate (); Q_INVOKABLE void startRecording (); Q_INVOKABLE void stopRecording (); Q_INVOKABLE void join (); Q_INVOKABLE void leave (); signals: void countChanged (int count); void microMutedChanged (bool status); void recordingChanged (bool status); void conferenceChanged (); private: int getCount () const { return rowCount(); } bool getMicroMuted () const; void setMicroMuted (bool status); float getMicroVu () const; bool isInConference () const; bool getRecording () const; bool mRecording = false; }; #endif // CONFERENCE_MODEL_H_ linphone-desktop-4.2.5/linphone-app/src/components/contact/000077500000000000000000000000001376717241300240215ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/src/components/contact/ContactModel.cpp000066400000000000000000000145541376717241300271120ustar00rootroot00000000000000/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include #include "app/App.hpp" #include "ContactModel.hpp" #include "VcardModel.hpp" // ============================================================================= using namespace std; ContactModel::ContactModel (QObject *parent, shared_ptr linphoneFriend) : QObject(parent) { Q_CHECK_PTR(linphoneFriend); mLinphoneFriend = linphoneFriend; mLinphoneFriend->setData("contact-model", *this); setVcardModelInternal(new VcardModel(linphoneFriend->getVcard())); } ContactModel::ContactModel (QObject *parent, VcardModel *vcardModel) : QObject(parent) { Q_CHECK_PTR(vcardModel); Q_CHECK_PTR(vcardModel->mVcard); Q_ASSERT(!vcardModel->mIsReadOnly); mLinphoneFriend = linphone::Friend::newFromVcard(vcardModel->mVcard); mLinphoneFriend->setData("contact-model", *this); qInfo() << QStringLiteral("Create contact from vcard:") << this << vcardModel; setVcardModelInternal(vcardModel); } // ----------------------------------------------------------------------------- void ContactModel::refreshPresence () { Presence::PresenceStatus status = static_cast( mLinphoneFriend->getConsolidatedPresence() ); emit presenceStatusChanged(status); emit presenceLevelChanged(Presence::getPresenceLevel(status)); } // ----------------------------------------------------------------------------- VcardModel *ContactModel::getVcardModel () const { return mVcardModel; } void ContactModel::setVcardModel (VcardModel *vcardModel) { VcardModel *oldVcardModel = mVcardModel; qInfo() << QStringLiteral("Remove vcard on contact:") << this << oldVcardModel; oldVcardModel->mIsReadOnly = false; oldVcardModel->mAvatarIsReadOnly = vcardModel->getAvatar() == oldVcardModel->getAvatar(); oldVcardModel->deleteLater(); qInfo() << QStringLiteral("Set vcard on contact:") << this << vcardModel; setVcardModelInternal(vcardModel); // Flush vcard. mLinphoneFriend->done(); updateSipAddresses(oldVcardModel); } void ContactModel::setVcardModelInternal (VcardModel *vcardModel) { Q_CHECK_PTR(vcardModel); Q_ASSERT(vcardModel != mVcardModel); mVcardModel = vcardModel; mVcardModel->mAvatarIsReadOnly = false; mVcardModel->mIsReadOnly = true; App::getInstance()->getEngine()->setObjectOwnership(mVcardModel, QQmlEngine::CppOwnership); mVcardModel->setParent(this); if (mLinphoneFriend->getVcard() != vcardModel->mVcard) mLinphoneFriend->setVcard(vcardModel->mVcard); } void ContactModel::updateSipAddresses (VcardModel *oldVcardModel) { Q_CHECK_PTR(oldVcardModel); QVariantList oldSipAddresses = oldVcardModel->getSipAddresses(); QVariantList sipAddresses = mVcardModel->getSipAddresses(); QSet done; for (const auto &variantA : oldSipAddresses) { next: const QString sipAddress = variantA.toString(); if (done.contains(sipAddress)) continue; done.insert(sipAddress); // Check if old sip address exists in new set => No changes. for (const auto &variantB : sipAddresses) { if (sipAddress == variantB.toString()) goto next; } emit sipAddressRemoved(sipAddress); } oldSipAddresses.clear(); for (const auto &variant : sipAddresses) { const QString sipAddress = variant.toString(); if (done.contains(sipAddress)) continue; done.insert(sipAddress); emit sipAddressAdded(sipAddress); } emit contactUpdated(); } // ----------------------------------------------------------------------------- void ContactModel::mergeVcardModel (VcardModel *vcardModel) { Q_CHECK_PTR(vcardModel); qInfo() << QStringLiteral("Merge vcard into contact:") << this << vcardModel; // 1. Merge avatar. if (vcardModel->getAvatar().isEmpty()) vcardModel->setAvatar(mVcardModel->getAvatar()); // 2. Merge sip addresses, companies, emails and urls. for (const auto &sipAddress : mVcardModel->getSipAddresses()) vcardModel->addSipAddress(sipAddress.toString()); for (const auto &company : mVcardModel->getCompanies()) vcardModel->addCompany(company.toString()); for (const auto &email : mVcardModel->getEmails()) vcardModel->addEmail(email.toString()); for (const auto &url : mVcardModel->getUrls()) vcardModel->addUrl(url.toString()); // 3. Merge address. { const QVariantMap oldAddress = vcardModel->getAddress(); QVariantMap newAddress = vcardModel->getAddress(); constexpr const char *attributes[4] = { "street", "locality", "postalCode", "country" }; bool needMerge = true; for (const auto &attribute : attributes) if (!newAddress[attribute].toString().isEmpty()) { needMerge = false; break; } if (needMerge) { for (const auto &attribute : attributes) newAddress[attribute] = oldAddress[attribute]; } } setVcardModel(vcardModel); } // ----------------------------------------------------------------------------- VcardModel *ContactModel::cloneVcardModel () const { shared_ptr vcard = mVcardModel->mVcard->clone(); Q_CHECK_PTR(vcard); Q_CHECK_PTR(vcard->getVcard()); mLinphoneFriend->edit(); VcardModel *vcardModel = new VcardModel(vcard); vcardModel->mIsReadOnly = false; qInfo() << QStringLiteral("Clone vcard from contact:") << this << vcardModel; return vcardModel; } // ----------------------------------------------------------------------------- Presence::PresenceStatus ContactModel::getPresenceStatus () const { return static_cast(mLinphoneFriend->getConsolidatedPresence()); } Presence::PresenceLevel ContactModel::getPresenceLevel () const { return Presence::getPresenceLevel(getPresenceStatus()); } linphone-desktop-4.2.5/linphone-app/src/components/contact/ContactModel.hpp000066400000000000000000000047341376717241300271160ustar00rootroot00000000000000/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef CONTACT_MODEL_H_ #define CONTACT_MODEL_H_ #include "components/presence/Presence.hpp" // ============================================================================= class VcardModel; class ContactModel : public QObject { // Grant access to `mLinphoneFriend`. friend class ContactsListModel; friend class ContactsListProxyModel; friend class SipAddressesProxyModel; Q_OBJECT; Q_PROPERTY(Presence::PresenceStatus presenceStatus READ getPresenceStatus NOTIFY presenceStatusChanged); Q_PROPERTY(Presence::PresenceLevel presenceLevel READ getPresenceLevel NOTIFY presenceLevelChanged); Q_PROPERTY(VcardModel * vcard READ getVcardModel WRITE setVcardModel NOTIFY contactUpdated); public: ContactModel (QObject *parent, std::shared_ptr linphoneFriend); ContactModel (QObject *parent, VcardModel *vcardModel); void refreshPresence (); VcardModel *getVcardModel () const; void setVcardModel (VcardModel *vcardModel); void mergeVcardModel (VcardModel *vcardModel); Q_INVOKABLE VcardModel *cloneVcardModel () const; signals: void contactUpdated (); void presenceStatusChanged (Presence::PresenceStatus status); void presenceLevelChanged (Presence::PresenceLevel level); void sipAddressAdded (const QString &sipAddress); void sipAddressRemoved (const QString &sipAddress); private: void setVcardModelInternal (VcardModel *vcardModel); void updateSipAddresses (VcardModel *oldVcardModel); Presence::PresenceStatus getPresenceStatus () const; Presence::PresenceLevel getPresenceLevel () const; VcardModel *mVcardModel = nullptr; std::shared_ptr mLinphoneFriend; }; Q_DECLARE_METATYPE(ContactModel *); #endif // CONTACT_MODEL_H_ linphone-desktop-4.2.5/linphone-app/src/components/contact/VcardModel.cpp000066400000000000000000000401211376717241300265430ustar00rootroot00000000000000/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include #include #include #include #include "app/App.hpp" #include "app/paths/Paths.hpp" #include "app/providers/AvatarProvider.hpp" #include "components/core/CoreManager.hpp" #include "components/sip-addresses/SipAddressesModel.hpp" #include "utils/Utils.hpp" #include "VcardModel.hpp" // ============================================================================= using namespace std; #define CHECK_VCARD_IS_WRITABLE(VCARD) Q_ASSERT(VCARD->mIsReadOnly == false) namespace { constexpr char VcardScheme[] = "linphone-desktop:/"; } template static inline shared_ptr findBelCardValue (const list> &list, const string &value) { auto it = find_if(list.cbegin(), list.cend(), [&value](const shared_ptr &entry) { return value == entry->getValue(); }); return it != list.cend() ? *it : nullptr; } template static inline shared_ptr findBelCardValue (const list> &list, const QString &value) { return findBelCardValue(list, Utils::appStringToCoreString(value)); } static inline bool isLinphoneDesktopPhoto (const shared_ptr &photo) { return !photo->getValue().compare(0, sizeof(VcardScheme) - 1, VcardScheme); } static shared_ptr findBelcardPhoto (const shared_ptr &belcard) { const list> &photos = belcard->getPhotos(); auto it = find_if(photos.cbegin(), photos.cend(), isLinphoneDesktopPhoto); if (it != photos.cend()) return *it; return nullptr; } static void removeBelcardPhoto (const shared_ptr &belcard, bool cleanPathsOnly = false) { list> photos; for (const auto photo : belcard->getPhotos()) { if (isLinphoneDesktopPhoto(photo)) photos.push_back(photo); } for (const auto photo : photos) { QString imagePath( Utils::coreStringToAppString( Paths::getAvatarsDirPath() + photo->getValue().substr(sizeof(VcardScheme) - 1) ) ); if (!cleanPathsOnly) { if (!QFile::remove(imagePath)) qWarning() << QStringLiteral("Unable to remove `%1`.").arg(imagePath); else qInfo() << QStringLiteral("Remove `%1`.").arg(imagePath); } belcard->removePhoto(photo); } } // ----------------------------------------------------------------------------- VcardModel::VcardModel (shared_ptr vcard, bool isReadOnly) { Q_CHECK_PTR(vcard); mVcard = vcard; mIsReadOnly = isReadOnly; } VcardModel::~VcardModel () { if (!mIsReadOnly) { qInfo() << QStringLiteral("Destroy detached vcard:") << this; if (!mAvatarIsReadOnly) removeBelcardPhoto(mVcard->getVcard()); } else qInfo() << QStringLiteral("Destroy attached vcard:") << this; } // ----------------------------------------------------------------------------- QString VcardModel::getAvatar () const { // Find desktop avatar. shared_ptr photo = findBelcardPhoto(mVcard->getVcard()); // No path found. if (!photo) return QString(""); // Returns right path. return QStringLiteral("image://%1/%2").arg(AvatarProvider::ProviderId).arg( Utils::coreStringToAppString(photo->getValue().substr(sizeof(VcardScheme) - 1)) ); } static inline QString getFileIdFromAppPath (const QString &path) { const static QString appPrefix = QStringLiteral("image://%1/").arg(AvatarProvider::ProviderId); return path.mid(appPrefix.length()); } bool VcardModel::setAvatar (const QString &path) { CHECK_VCARD_IS_WRITABLE(this); shared_ptr belcard = mVcard->getVcard(); QString fileId; QFile file; // 1. Try to copy photo in avatars folder if it's a right path file and // not an application path like `image:`. if (!path.isEmpty()) { if (path.startsWith("image:")) fileId = getFileIdFromAppPath(path); else { file.setFileName(path); if (!file.exists() || QImageReader::imageFormat(path).size() == 0) return false; QFileInfo info(file); QString uuid = QUuid::createUuid().toString(); fileId = QStringLiteral("%1.%2") .arg(uuid.mid(1, uuid.length() - 2)) // Remove `{}`. .arg(info.suffix()); QString dest = Utils::coreStringToAppString(Paths::getAvatarsDirPath()) + fileId; if (!file.copy(dest)) return false; qInfo() << QStringLiteral("Update avatar of `%1`. (path=%2)").arg(getUsername()).arg(dest); } } // 2. Remove oldest photo. removeBelcardPhoto(belcard, mAvatarIsReadOnly); mAvatarIsReadOnly = false; // 3. Update new photo. if (!path.isEmpty()) { shared_ptr photo = belcard::BelCardGeneric::create(); photo->setValue(VcardScheme + Utils::appStringToCoreString(fileId)); if (!belcard->addPhoto(photo)) { file.remove(); return false; } } emit vcardUpdated(); return true; } // ----------------------------------------------------------------------------- QString VcardModel::getUsername () const { return decode(QString::fromStdString(mVcard->getFullName()));// Is in UTF8 } void VcardModel::setUsername (const QString &username) { CHECK_VCARD_IS_WRITABLE(this); if (username.length() == 0 || username == getUsername()) return; mVcard->setFullName(encode(username).toStdString()); emit vcardUpdated(); } // ----------------------------------------------------------------------------- static inline shared_ptr getOrCreateBelCardAddress (shared_ptr belcard) { list> addresses = belcard->getAddresses(); shared_ptr address; if (addresses.empty()) { address = belcard::BelCardGeneric::create(); if (!belcard->addAddress(address)) qWarning() << "Unable to create a new address on vcard."; } else address = addresses.front(); return address; } QVariantMap VcardModel::getAddress () const { list> addresses = mVcard->getVcard()->getAddresses(); QVariantMap map; if (addresses.empty()) return map; shared_ptr address = addresses.front(); map["street"] = Utils::coreStringToAppString(address->getStreet()); map["locality"] = Utils::coreStringToAppString(address->getLocality()); map["postalCode"] = Utils::coreStringToAppString(address->getPostalCode()); map["country"] = Utils::coreStringToAppString(address->getCountry()); return map; } void VcardModel::setStreet (const QString &street) { CHECK_VCARD_IS_WRITABLE(this); shared_ptr address = getOrCreateBelCardAddress(mVcard->getVcard()); address->setStreet(Utils::appStringToCoreString(street)); emit vcardUpdated(); } void VcardModel::setLocality (const QString &locality) { CHECK_VCARD_IS_WRITABLE(this); shared_ptr address = getOrCreateBelCardAddress(mVcard->getVcard()); address->setLocality(Utils::appStringToCoreString(locality)); emit vcardUpdated(); } void VcardModel::setPostalCode (const QString &postalCode) { CHECK_VCARD_IS_WRITABLE(this); shared_ptr address = getOrCreateBelCardAddress(mVcard->getVcard()); address->setPostalCode(Utils::appStringToCoreString(postalCode)); emit vcardUpdated(); } void VcardModel::setCountry (const QString &country) { CHECK_VCARD_IS_WRITABLE(this); shared_ptr address = getOrCreateBelCardAddress(mVcard->getVcard()); address->setCountry(Utils::appStringToCoreString(country)); emit vcardUpdated(); } // ----------------------------------------------------------------------------- QVariantList VcardModel::getSipAddresses () const { shared_ptr core = CoreManager::getInstance()->getCore(); QVariantList list; for (const auto &address : mVcard->getVcard()->getImpp()) { string value = address->getValue(); shared_ptr linphoneAddress = core->createAddress(value); if (linphoneAddress) list << Utils::coreStringToAppString(linphoneAddress->asStringUriOnly()); else qWarning() << QStringLiteral("Unable to parse sip address: `%1`") .arg(Utils::coreStringToAppString(value)); } return list; } bool VcardModel::addSipAddress (const QString &sipAddress) { CHECK_VCARD_IS_WRITABLE(this); string interpretedSipAddress = Utils::appStringToCoreString(SipAddressesModel::interpretSipAddress(sipAddress)); if (interpretedSipAddress.empty()) return false; // Add sip address in belcard. shared_ptr belcard = mVcard->getVcard(); if (findBelCardValue(belcard->getImpp(), interpretedSipAddress)) return false; shared_ptr value = belcard::BelCardGeneric::create(); value->setValue(interpretedSipAddress); if (!belcard->addImpp(value)) { qWarning() << QStringLiteral("Unable to add sip address on vcard: `%1`.").arg(sipAddress); return false; } qInfo() << QStringLiteral("Add new sip address on vcard: `%1`.").arg(sipAddress); emit vcardUpdated(); return true; } void VcardModel::removeSipAddress (const QString &sipAddress) { CHECK_VCARD_IS_WRITABLE(this); shared_ptr belcard = mVcard->getVcard(); list> addresses = belcard->getImpp(); shared_ptr value = findBelCardValue( addresses, Utils::appStringToCoreString(SipAddressesModel::interpretSipAddress(sipAddress)) ); if (!value) { qWarning() << QStringLiteral("Unable to remove sip address on vcard: `%1`.").arg(sipAddress); return; } if (addresses.size() == 1) { qWarning() << QStringLiteral("Unable to remove the only existing sip address on vcard: `%1`.") .arg(sipAddress); return; } qInfo() << QStringLiteral("Remove sip address on vcard: `%1`.").arg(sipAddress); belcard->removeImpp(value); emit vcardUpdated(); } bool VcardModel::updateSipAddress (const QString &oldSipAddress, const QString &sipAddress) { bool soFarSoGood = addSipAddress(sipAddress); removeSipAddress(oldSipAddress); // Remove after. Avoid `Unable to remove the only sip address...` error. return soFarSoGood; } // ----------------------------------------------------------------------------- QVariantList VcardModel::getCompanies () const { QVariantList list; for (const auto &company : mVcard->getVcard()->getRoles()) list.append(Utils::coreStringToAppString(company->getValue())); return list; } bool VcardModel::addCompany (const QString &company) { CHECK_VCARD_IS_WRITABLE(this); shared_ptr belcard = mVcard->getVcard(); if (findBelCardValue(belcard->getRoles(), company)) return false; shared_ptr value = belcard::BelCardGeneric::create(); value->setValue(Utils::appStringToCoreString(company)); if (!belcard->addRole(value)) { qWarning() << QStringLiteral("Unable to add company on vcard: `%1`.").arg(company); return false; } qInfo() << QStringLiteral("Add new company on vcard: `%1`.").arg(company); emit vcardUpdated(); return true; } void VcardModel::removeCompany (const QString &company) { CHECK_VCARD_IS_WRITABLE(this); shared_ptr belcard = mVcard->getVcard(); shared_ptr value = findBelCardValue(belcard->getRoles(), company); if (!value) { qWarning() << QStringLiteral("Unable to remove company on vcard: `%1`.").arg(company); return; } qInfo() << QStringLiteral("Remove company on vcard: `%1`.").arg(company); belcard->removeRole(value); emit vcardUpdated(); } bool VcardModel::updateCompany (const QString &oldCompany, const QString &company) { removeCompany(oldCompany); return addCompany(company); } // ----------------------------------------------------------------------------- QVariantList VcardModel::getEmails () const { QVariantList list; for (const auto &email : mVcard->getVcard()->getEmails()) list.append(Utils::coreStringToAppString(email->getValue())); return list; } bool VcardModel::addEmail (const QString &email) { CHECK_VCARD_IS_WRITABLE(this); shared_ptr belcard = mVcard->getVcard(); if (findBelCardValue(belcard->getEmails(), email)) return false; shared_ptr value = belcard::BelCardGeneric::create(); value->setValue(Utils::appStringToCoreString(email)); if (!belcard->addEmail(value)) { qWarning() << QStringLiteral("Unable to add email on vcard: `%1`.").arg(email); return false; } qInfo() << QStringLiteral("Add new email on vcard: `%1`.").arg(email); emit vcardUpdated(); return true; } void VcardModel::removeEmail (const QString &email) { CHECK_VCARD_IS_WRITABLE(this); shared_ptr belcard = mVcard->getVcard(); shared_ptr value = findBelCardValue(belcard->getEmails(), email); if (!value) { qWarning() << QStringLiteral("Unable to remove email on vcard: `%1`.").arg(email); return; } qInfo() << QStringLiteral("Remove email on vcard: `%1`.").arg(email); belcard->removeEmail(value); emit vcardUpdated(); } bool VcardModel::updateEmail (const QString &oldEmail, const QString &email) { removeEmail(oldEmail); return addEmail(email); } // ----------------------------------------------------------------------------- QVariantList VcardModel::getUrls () const { QVariantList list; for (const auto &url : mVcard->getVcard()->getURLs()) list.append(Utils::coreStringToAppString(url->getValue())); return list; } bool VcardModel::addUrl (const QString &url) { CHECK_VCARD_IS_WRITABLE(this); shared_ptr belcard = mVcard->getVcard(); if (findBelCardValue(belcard->getURLs(), url)) return false; shared_ptr value = belcard::BelCardGeneric::create(); value->setValue(Utils::appStringToCoreString(url)); if (!belcard->addURL(value)) { qWarning() << QStringLiteral("Unable to add url on vcard: `%1`.").arg(url); return false; } qInfo() << QStringLiteral("Add new url on vcard: `%1`.").arg(url); emit vcardUpdated(); return true; } void VcardModel::removeUrl (const QString &url) { CHECK_VCARD_IS_WRITABLE(this); shared_ptr belcard = mVcard->getVcard(); shared_ptr value = findBelCardValue(belcard->getURLs(), url); if (!value) { qWarning() << QStringLiteral("Unable to remove url on vcard: `%1`.").arg(url); return; } qInfo() << QStringLiteral("Remove url on vcard: `%1`.").arg(url); belcard->removeURL(value); emit vcardUpdated(); } bool VcardModel::updateUrl (const QString &oldUrl, const QString &url) { removeUrl(oldUrl); return addUrl(url); } QString VcardModel::encode(const QString& data)const{// Convert '\n', ',', '\' to "\n", "\,", "\\" QString encoded; for(int i = 0 ; i < data.length() ; ++i){ if(data[i] == ',') encoded += "\\,"; else if(data[i] == '\\') encoded += "\\\\"; else if(data[i] == '\n') encoded += "\\n"; else encoded += data[i]; } return encoded; } QString VcardModel::decode(const QString& data)const{// Convert "\n", "\,", "\\" to '\n', ',', '\' QString decoded = data; decoded.replace("\\,", ",").replace("\\\\", "\\").replace("\\n", "\n"); return decoded; } linphone-desktop-4.2.5/linphone-app/src/components/contact/VcardModel.hpp000066400000000000000000000100371376717241300265530ustar00rootroot00000000000000/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef VCARD_MODEL_H_ #define VCARD_MODEL_H_ #include #include // ============================================================================= namespace linphone { class Vcard; } class VcardModel : public QObject { friend class ContactModel; // Grant access to `mVcard`. Q_OBJECT; Q_PROPERTY(QString username READ getUsername WRITE setUsername NOTIFY vcardUpdated); Q_PROPERTY(QString avatar READ getAvatar WRITE setAvatar NOTIFY vcardUpdated); Q_PROPERTY(QVariantMap address READ getAddress NOTIFY vcardUpdated); Q_PROPERTY(QVariantList sipAddresses READ getSipAddresses NOTIFY vcardUpdated); Q_PROPERTY(QVariantList companies READ getCompanies NOTIFY vcardUpdated); Q_PROPERTY(QVariantList emails READ getEmails NOTIFY vcardUpdated); Q_PROPERTY(QVariantList urls READ getUrls NOTIFY vcardUpdated); // --------------------------------------------------------------------------- public: VcardModel (std::shared_ptr vcard, bool isReadOnly = true); ~VcardModel (); // --------------------------------------------------------------------------- bool getIsReadOnly () const { return mIsReadOnly; } // --------------------------------------------------------------------------- QString getAvatar () const; bool setAvatar (const QString &path); QString getUsername () const; void setUsername (const QString &username); // --------------------------------------------------------------------------- QVariantList getSipAddresses () const; QVariantMap getAddress () const; QVariantList getEmails () const; QVariantList getCompanies () const; QVariantList getUrls () const; // --------------------------------------------------------------------------- Q_INVOKABLE bool addSipAddress (const QString &sipAddress); Q_INVOKABLE void removeSipAddress (const QString &sipAddress); Q_INVOKABLE bool updateSipAddress (const QString &oldSipAddress, const QString &sipAddress); Q_INVOKABLE bool addCompany (const QString &company); Q_INVOKABLE void removeCompany (const QString &company); Q_INVOKABLE bool updateCompany (const QString &oldCompany, const QString &company); Q_INVOKABLE bool addEmail (const QString &email); Q_INVOKABLE void removeEmail (const QString &email); Q_INVOKABLE bool updateEmail (const QString &oldEmail, const QString &email); Q_INVOKABLE bool addUrl (const QString &url); Q_INVOKABLE void removeUrl (const QString &url); Q_INVOKABLE bool updateUrl (const QString &oldUrl, const QString &url); Q_INVOKABLE void setStreet (const QString &street); Q_INVOKABLE void setLocality (const QString &locality); Q_INVOKABLE void setPostalCode (const QString &postalCode); Q_INVOKABLE void setCountry (const QString &country); // --------------------------------------------------------------------------- QString encode(const QString& data)const;// Convert '\n', ',', '\' to "\n", "\,", "\\" QString decode(const QString& data)const;// Convert "\n", "\,", "\\" to '\n', ',', '\' signals: void vcardUpdated (); // --------------------------------------------------------------------------- private: bool mIsReadOnly = true; bool mAvatarIsReadOnly = true; std::shared_ptr mVcard; }; Q_DECLARE_METATYPE(VcardModel *); #endif // VCARD_MODEL_H_ linphone-desktop-4.2.5/linphone-app/src/components/contacts/000077500000000000000000000000001376717241300242045ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/src/components/contacts/ContactsListModel.cpp000066400000000000000000000144051376717241300303070ustar00rootroot00000000000000/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include #include "app/App.hpp" #include "components/contact/ContactModel.hpp" #include "components/contact/VcardModel.hpp" #include "components/core/CoreManager.hpp" #include "ContactsListModel.hpp" // ============================================================================= using namespace std; ContactsListModel::ContactsListModel (QObject *parent) : QAbstractListModel(parent) { mLinphoneFriends = CoreManager::getInstance()->getCore()->getFriendsLists().front(); // Clean friends. { list> toRemove; for (const auto &linphoneFriend : mLinphoneFriends->getFriends()) { if (!linphoneFriend->getVcard()) toRemove.push_back(linphoneFriend); } for (const auto &linphoneFriend : toRemove) { qWarning() << QStringLiteral("Remove one friend without vcard."); mLinphoneFriends->removeFriend(linphoneFriend); } } // Init contacts with linphone friends list. QQmlEngine *engine = App::getInstance()->getEngine(); for (const auto &linphoneFriend : mLinphoneFriends->getFriends()) { ContactModel *contact = new ContactModel(this, linphoneFriend); // See: http://doc.qt.io/qt-5/qtqml-cppintegration-data.html#data-ownership // The returned value must have a explicit parent or a QQmlEngine::CppOwnership. engine->setObjectOwnership(contact, QQmlEngine::CppOwnership); addContact(contact); } } int ContactsListModel::rowCount (const QModelIndex &) const { return mList.count(); } QHash ContactsListModel::roleNames () const { QHash roles; roles[Qt::DisplayRole] = "$contact"; return roles; } QVariant ContactsListModel::data (const QModelIndex &index, int role) const { int row = index.row(); if (!index.isValid() || row < 0 || row >= mList.count()) return QVariant(); if (role == Qt::DisplayRole) return QVariant::fromValue(mList[row]); return QVariant(); } bool ContactsListModel::removeRow (int row, const QModelIndex &parent) { return removeRows(row, 1, parent); } bool ContactsListModel::removeRows (int row, int count, const QModelIndex &parent) { int limit = row + count - 1; if (row < 0 || count < 0 || limit >= mList.count()) return false; beginRemoveRows(parent, row, limit); for (int i = 0; i < count; ++i) { ContactModel *contact = mList.takeAt(row); mLinphoneFriends->removeFriend(contact->mLinphoneFriend); emit contactRemoved(contact); contact->deleteLater(); } endRemoveRows(); return true; } // ----------------------------------------------------------------------------- ContactModel *ContactsListModel::findContactModelFromSipAddress (const QString &sipAddress) const { auto it = find_if(mList.begin(), mList.end(), [&sipAddress](ContactModel *contactModel) { return contactModel->getVcardModel()->getSipAddresses().contains(sipAddress); }); return it != mList.end() ? *it : nullptr; } ContactModel *ContactsListModel::findContactModelFromUsername (const QString &username) const { auto it = find_if(mList.begin(), mList.end(), [&username](ContactModel *contactModel) { return contactModel->getVcardModel()->getUsername() == username; }); return it != mList.end() ? *it : nullptr; } // ----------------------------------------------------------------------------- ContactModel *ContactsListModel::addContact (VcardModel *vcardModel) { // Try to merge vcardModel to an existing contact. ContactModel *contact = findContactModelFromUsername(vcardModel->getUsername()); if (contact) { contact->mergeVcardModel(vcardModel); return contact; } contact = new ContactModel(this, vcardModel); App::getInstance()->getEngine()->setObjectOwnership(contact, QQmlEngine::CppOwnership); if (mLinphoneFriends->addFriend(contact->mLinphoneFriend) != linphone::FriendList::Status::OK) { qWarning() << QStringLiteral("Unable to add contact from vcard:") << vcardModel; delete contact; return nullptr; } qInfo() << QStringLiteral("Add contact from vcard:") << contact << vcardModel; // Make sure new subscribe is issued. mLinphoneFriends->updateSubscriptions(); int row = mList.count(); beginInsertRows(QModelIndex(), row, row); addContact(contact); endInsertRows(); emit contactAdded(contact); return contact; } void ContactsListModel::removeContact (ContactModel *contact) { qInfo() << QStringLiteral("Removing contact:") << contact; int index = mList.indexOf(contact); if (index == -1 || !removeRow(index)) qWarning() << QStringLiteral("Unable to remove contact:") << contact; } // ----------------------------------------------------------------------------- void ContactsListModel::cleanAvatars () { qInfo() << QStringLiteral("Delete all avatars."); for (const auto &contact : mList) { VcardModel *vcardModel = contact->cloneVcardModel(); vcardModel->setAvatar(QString("")); contact->setVcardModel(vcardModel); } } // ----------------------------------------------------------------------------- void ContactsListModel::addContact (ContactModel *contact) { QObject::connect(contact, &ContactModel::contactUpdated, this, [this, contact]() { emit contactUpdated(contact); }); QObject::connect(contact, &ContactModel::sipAddressAdded, this, [this, contact](const QString &sipAddress) { emit sipAddressAdded(contact, sipAddress); }); QObject::connect(contact, &ContactModel::sipAddressRemoved, this, [this, contact](const QString &sipAddress) { emit sipAddressRemoved(contact, sipAddress); }); mList << contact; } linphone-desktop-4.2.5/linphone-app/src/components/contacts/ContactsListModel.hpp000066400000000000000000000045701376717241300303160ustar00rootroot00000000000000/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef CONTACTS_LIST_MODEL_H_ #define CONTACTS_LIST_MODEL_H_ #include #include // ============================================================================= namespace linphone { class FriendList; } class ContactModel; class VcardModel; class ContactsListModel : public QAbstractListModel { friend class SipAddressesModel; Q_OBJECT; public: ContactsListModel (QObject *parent = Q_NULLPTR); int rowCount (const QModelIndex &index = QModelIndex()) const override; QHash roleNames () const override; QVariant data (const QModelIndex &index, int role = Qt::DisplayRole) const override; bool removeRow (int row, const QModelIndex &parent = QModelIndex()); bool removeRows (int row, int count, const QModelIndex &parent = QModelIndex()) override; ContactModel *findContactModelFromSipAddress (const QString &sipAddress) const; ContactModel *findContactModelFromUsername (const QString &username) const; Q_INVOKABLE ContactModel *addContact (VcardModel *vcardModel); Q_INVOKABLE void removeContact (ContactModel *contact); Q_INVOKABLE void cleanAvatars (); signals: void contactAdded (ContactModel *contact); void contactRemoved (const ContactModel *contact); void contactUpdated (ContactModel *contact); void sipAddressAdded (ContactModel *contact, const QString &sipAddress); void sipAddressRemoved (ContactModel *contact, const QString &sipAddress); private: void addContact (ContactModel *contact); QList mList; std::shared_ptr mLinphoneFriends; }; #endif // CONTACTS_LIST_MODEL_H_ linphone-desktop-4.2.5/linphone-app/src/components/contacts/ContactsListProxyModel.cpp000066400000000000000000000116431376717241300313520ustar00rootroot00000000000000/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include #include "components/contact/ContactModel.hpp" #include "components/contact/VcardModel.hpp" #include "components/core/CoreManager.hpp" #include "utils/Utils.hpp" #include "ContactsListModel.hpp" #include "ContactsListProxyModel.hpp" // ============================================================================= using namespace std; namespace { constexpr float UsernameWeight = 50.f; constexpr float SipAddressWeight = 50.f; constexpr float FactorPos0 = 1.0f; constexpr float FactorPos1 = 0.9f; constexpr float FactorPos2 = 0.8f; constexpr float FactorPos3 = 0.7f; constexpr float FactorPosOther = 0.6f; } // Notes: // // - First `^` is necessary to search two words with one separator // between them like `Claire Manning`. // // - [^_.-;@ ] is used to search patterns which starts with // a separator like ` word`. // // - [_.-;@ ] is the main pattern (a separator). const QRegExp ContactsListProxyModel::SearchSeparators("^[^_.-;@ ][_.-;@ ]"); // ----------------------------------------------------------------------------- ContactsListProxyModel::ContactsListProxyModel (QObject *parent) : QSortFilterProxyModel(parent) { setSourceModel(CoreManager::getInstance()->getContactsListModel()); sort(0); } // ----------------------------------------------------------------------------- void ContactsListProxyModel::setFilter (const QString &pattern) { mFilter = pattern; invalidate(); } // ----------------------------------------------------------------------------- bool ContactsListProxyModel::filterAcceptsRow ( int sourceRow, const QModelIndex &sourceParent ) const { const QModelIndex index = sourceModel()->index(sourceRow, 0, sourceParent); const ContactModel *contact = index.data().value(); mWeights[contact] = uint(round(computeContactWeight(contact))); return mWeights[contact] > 0 && ( !mUseConnectedFilter || contact->getPresenceLevel() != Presence::PresenceLevel::White ); } bool ContactsListProxyModel::lessThan (const QModelIndex &left, const QModelIndex &right) const { const ContactModel *contactA = sourceModel()->data(left).value(); const ContactModel *contactB = sourceModel()->data(right).value(); unsigned int weightA = mWeights[contactA]; unsigned int weightB = mWeights[contactB]; // Sort by weight and name. return weightA > weightB || ( weightA == weightB && contactA->mLinphoneFriend->getName() <= contactB->mLinphoneFriend->getName() ); } // ----------------------------------------------------------------------------- float ContactsListProxyModel::computeStringWeight (const QString &string, float percentage) const { int index = -1; int offset = -1; // Search pattern. while ((index = string.indexOf(mFilter, index + 1, Qt::CaseInsensitive)) != -1) { // Search n chars between one separator and index. int tmpOffset = index - string.lastIndexOf(SearchSeparators, index) - 1; if ((tmpOffset != -1 && tmpOffset < offset) || offset == -1) if ((offset = tmpOffset) == 0) break; } switch (offset) { case -1: return 0; case 0: return percentage *FactorPos0; case 1: return percentage *FactorPos1; case 2: return percentage *FactorPos2; case 3: return percentage *FactorPos3; default: break; } return percentage *FactorPosOther; } float ContactsListProxyModel::computeContactWeight (const ContactModel *contact) const { float weight = computeStringWeight(contact->getVcardModel()->getUsername(), UsernameWeight); // Get all contact's addresses. const list> addresses = contact->mLinphoneFriend->getAddresses(); float size = float(addresses.size()); for (auto it = addresses.cbegin(); it != addresses.cend(); ++it) weight += computeStringWeight( Utils::coreStringToAppString((*it)->asStringUriOnly()), SipAddressWeight / size ); return weight; } // ----------------------------------------------------------------------------- void ContactsListProxyModel::setConnectedFilter (bool useConnectedFilter) { if (useConnectedFilter != mUseConnectedFilter) { mUseConnectedFilter = useConnectedFilter; invalidate(); } } linphone-desktop-4.2.5/linphone-app/src/components/contacts/ContactsListProxyModel.hpp000066400000000000000000000040731376717241300313560ustar00rootroot00000000000000/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef CONTACTS_LIST_PROXY_MODEL_H_ #define CONTACTS_LIST_PROXY_MODEL_H_ #include // ============================================================================= class ContactModel; class ContactsListModel; class ContactsListProxyModel : public QSortFilterProxyModel { Q_OBJECT; Q_PROPERTY( bool useConnectedFilter READ isConnectedFilterUsed WRITE setConnectedFilter ); public: ContactsListProxyModel (QObject *parent = Q_NULLPTR); Q_INVOKABLE void setFilter (const QString &pattern); protected: bool filterAcceptsRow (int sourceRow, const QModelIndex &sourceParent) const override; bool lessThan (const QModelIndex &left, const QModelIndex &right) const override; private: float computeStringWeight (const QString &string, float percentage) const; float computeContactWeight (const ContactModel *contact) const; bool isConnectedFilterUsed () const { return mUseConnectedFilter; } void setConnectedFilter (bool useConnectedFilter); QString mFilter; bool mUseConnectedFilter = false; // It's just a cache to save values computed by `filterAcceptsRow` // and reused by `lessThan`. mutable QHash mWeights; static const QRegExp SearchSeparators; }; #endif // CONTACTS_LIST_PROXY_MODEL_H_ linphone-desktop-4.2.5/linphone-app/src/components/core/000077500000000000000000000000001376717241300233165ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/src/components/core/CoreHandlers.cpp000066400000000000000000000220161376717241300263740ustar00rootroot00000000000000/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include #include #include #include #include "app/App.hpp" #include "components/call/CallModel.hpp" #include "components/contact/ContactModel.hpp" #include "components/notifier/Notifier.hpp" #include "components/settings/AccountSettingsModel.hpp" #include "components/settings/SettingsModel.hpp" #include "utils/Utils.hpp" #include "CoreHandlers.hpp" #include "CoreManager.hpp" // ============================================================================= using namespace std; // Schedule a function in app context. void scheduleFunctionInApp (function func) { App *app = App::getInstance(); if (QThread::currentThread() != app->thread()) QTimer::singleShot(0, app, func); else func(); } // ----------------------------------------------------------------------------- CoreHandlers::CoreHandlers (CoreManager *coreManager) { mCoreStartedLock = new QMutex(); QObject::connect(coreManager, &CoreManager::coreCreated, this, &CoreHandlers::handleCoreCreated); } CoreHandlers::~CoreHandlers () { delete mCoreStartedLock; } // ----------------------------------------------------------------------------- void CoreHandlers::handleCoreCreated () { mCoreStartedLock->lock(); Q_ASSERT(mCoreCreated == false); mCoreCreated = true; notifyCoreStarted(); mCoreStartedLock->unlock(); } void CoreHandlers::notifyCoreStarted () { if (mCoreCreated && mCoreStarted) scheduleFunctionInApp([this] { qInfo() << QStringLiteral("Core started."); emit coreStarted(); }); } // ----------------------------------------------------------------------------- void CoreHandlers::onAuthenticationRequested ( const shared_ptr & core, const shared_ptr &authInfo, linphone::AuthMethod method ) { Q_UNUSED(core) Q_UNUSED(method) if( authInfo ) { emit authenticationRequested(authInfo); } } void CoreHandlers::onCallEncryptionChanged ( const shared_ptr &, const shared_ptr &call, bool, const string & ) { emit callEncryptionChanged(call); } void CoreHandlers::onCallStateChanged ( const shared_ptr &, const shared_ptr &call, linphone::Call::State state, const string & ) { emit callStateChanged(call, state); SettingsModel *settingsModel = CoreManager::getInstance()->getSettingsModel(); if ( call->getState() == linphone::Call::State::IncomingReceived && ( !settingsModel->getAutoAnswerStatus() || settingsModel->getAutoAnswerDelay() > 0 ) ) App::getInstance()->getNotifier()->notifyReceivedCall(call); } void CoreHandlers::onCallStatsUpdated ( const shared_ptr &, const shared_ptr &call, const shared_ptr &stats ) { call->getData("call-model").updateStats(stats); } void CoreHandlers::onCallCreated(const shared_ptr &, const shared_ptr &call) { emit callCreated(call); } void CoreHandlers::onDtmfReceived( const std::shared_ptr & lc, const std::shared_ptr & call, int dtmf) { CoreManager::getInstance()->getCore()->playDtmf((char)dtmf, CallModel::DtmfSoundDelay); } void CoreHandlers::onGlobalStateChanged ( const shared_ptr &, linphone::GlobalState gstate, const string & ) { if (gstate == linphone::GlobalState::On) { mCoreStartedLock->lock(); Q_ASSERT(mCoreStarted == false); mCoreStarted = true; notifyCoreStarted(); mCoreStartedLock->unlock(); } } void CoreHandlers::onIsComposingReceived ( const shared_ptr &, const shared_ptr &room ) { emit isComposingChanged(room); } void CoreHandlers::onLogCollectionUploadStateChanged ( const shared_ptr &, linphone::Core::LogCollectionUploadState state, const string &info ) { emit logsUploadStateChanged(state, info); } void CoreHandlers::onLogCollectionUploadProgressIndication ( const shared_ptr &, size_t, size_t ) { // TODO; } void CoreHandlers::onMessageReceived ( const shared_ptr &core, const shared_ptr &chatRoom, const shared_ptr &message ) { const string contentType = message->getContentType(); if (contentType == "text/plain" || contentType == "application/vnd.gsma.rcs-ft-http+xml") { emit messageReceived(message); // 1. Do not notify if chat is not activated. CoreManager *coreManager = CoreManager::getInstance(); SettingsModel *settingsModel = coreManager->getSettingsModel(); if (!settingsModel->getChatEnabled()) return; // 2. Notify with Notification popup. const App *app = App::getInstance(); if (!app->hasFocus() || !chatRoom->getLocalAddress()->weakEqual(coreManager->getAccountSettingsModel()->getUsedSipAddress())) app->getNotifier()->notifyReceivedMessage(message); // 3. Notify with sound. if (!settingsModel->getChatNotificationSoundEnabled()) return; if ( !app->hasFocus() || !CoreManager::getInstance()->chatModelExists( Utils::coreStringToAppString(chatRoom->getPeerAddress()->asStringUriOnly()), Utils::coreStringToAppString(chatRoom->getLocalAddress()->asStringUriOnly()) ) ) core->playLocal(Utils::appStringToCoreString(settingsModel->getChatNotificationSoundPath())); } } void CoreHandlers::onNotifyPresenceReceivedForUriOrTel ( const shared_ptr &, const shared_ptr &, const string &uriOrTel, const shared_ptr &presenceModel ) { emit presenceReceived(Utils::coreStringToAppString(uriOrTel), presenceModel); } void CoreHandlers::onNotifyPresenceReceived ( const shared_ptr &, const shared_ptr &linphoneFriend ) { // Ignore friend without vcard because the `contact-model` data doesn't exist. if (linphoneFriend->getVcard()) linphoneFriend->getData("contact-model").refreshPresence(); } void CoreHandlers::onRegistrationStateChanged ( const shared_ptr &, const shared_ptr &proxyConfig, linphone::RegistrationState state, const string & ) { emit registrationStateChanged(proxyConfig, state); } void CoreHandlers::onTransferStateChanged ( const shared_ptr &, const shared_ptr &call, linphone::Call::State state ) { switch (state) { case linphone::Call::State::EarlyUpdatedByRemote: case linphone::Call::State::EarlyUpdating: case linphone::Call::State::Idle: case linphone::Call::State::IncomingEarlyMedia: case linphone::Call::State::IncomingReceived: case linphone::Call::State::OutgoingEarlyMedia: case linphone::Call::State::OutgoingRinging: case linphone::Call::State::Paused: case linphone::Call::State::PausedByRemote: case linphone::Call::State::Pausing: case linphone::Call::State::Referred: case linphone::Call::State::Released: case linphone::Call::State::Resuming: case linphone::Call::State::StreamsRunning: case linphone::Call::State::UpdatedByRemote: case linphone::Call::State::Updating: break; // Nothing. // 1. Init. case linphone::Call::State::OutgoingInit: qInfo() << QStringLiteral("Call transfer init."); break; // 2. In progress. case linphone::Call::State::OutgoingProgress: qInfo() << QStringLiteral("Call transfer in progress."); break; // 3. Done. case linphone::Call::State::Connected: qInfo() << QStringLiteral("Call transfer succeeded."); emit callTransferSucceeded(call); break; // 4. Error. case linphone::Call::State::End: case linphone::Call::State::Error: qWarning() << QStringLiteral("Call transfer failed."); emit callTransferFailed(call); break; } } void CoreHandlers::onVersionUpdateCheckResultReceived ( const shared_ptr &, linphone::VersionUpdateCheckResult result, const string &version, const string &url ) { if (result == linphone::VersionUpdateCheckResult::NewVersionAvailable) App::getInstance()->getNotifier()->notifyNewVersionAvailable( Utils::coreStringToAppString(version), Utils::coreStringToAppString(url) ); } linphone-desktop-4.2.5/linphone-app/src/components/core/CoreHandlers.hpp000066400000000000000000000130031376717241300263750ustar00rootroot00000000000000/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef CORE_HANDLERS_H_ #define CORE_HANDLERS_H_ #include #include // ============================================================================= class CoreManager; class QMutex; class CoreHandlers : public QObject, public linphone::CoreListener { Q_OBJECT; public: CoreHandlers (CoreManager *coreManager); ~CoreHandlers (); signals: void authenticationRequested (const std::shared_ptr &authInfo); void callEncryptionChanged (const std::shared_ptr &call); void callStateChanged (const std::shared_ptr &call, linphone::Call::State state); void callTransferFailed (const std::shared_ptr &call); void callTransferSucceeded (const std::shared_ptr &call); void callCreated(const std::shared_ptr & call); void coreStarted (); void isComposingChanged (const std::shared_ptr &chatRoom); void logsUploadStateChanged (linphone::Core::LogCollectionUploadState state, const std::string &info); void messageReceived (const std::shared_ptr &message); void presenceReceived (const QString &sipAddress, const std::shared_ptr &presenceModel); void registrationStateChanged (const std::shared_ptr &proxyConfig, linphone::RegistrationState state); private: void handleCoreCreated (); void notifyCoreStarted (); // --------------------------------------------------------------------------- // Linphone callbacks. // --------------------------------------------------------------------------- void onAuthenticationRequested ( const std::shared_ptr &core, const std::shared_ptr &authInfo, linphone::AuthMethod method ) override; void onCallEncryptionChanged ( const std::shared_ptr &core, const std::shared_ptr &call, bool on, const std::string &authenticationToken ) override; void onCallStateChanged ( const std::shared_ptr &core, const std::shared_ptr &call, linphone::Call::State state, const std::string &message ) override; void onCallStatsUpdated ( const std::shared_ptr &core, const std::shared_ptr &call, const std::shared_ptr &stats ) override; void onCallCreated( const std::shared_ptr & lc, const std::shared_ptr & call ) override; void onDtmfReceived( const std::shared_ptr & lc, const std::shared_ptr & call, int dtmf)override; void onGlobalStateChanged ( const std::shared_ptr &core, linphone::GlobalState gstate, const std::string &message ) override; void onIsComposingReceived ( const std::shared_ptr &core, const std::shared_ptr &room ) override; void onLogCollectionUploadStateChanged ( const std::shared_ptr &core, linphone::Core::LogCollectionUploadState state, const std::string &info ) override; void onLogCollectionUploadProgressIndication ( const std::shared_ptr &lc, size_t offset, size_t total ) override; void onMessageReceived ( const std::shared_ptr &core, const std::shared_ptr &room, const std::shared_ptr &message ) override; void onNotifyPresenceReceivedForUriOrTel ( const std::shared_ptr &core, const std::shared_ptr &linphoneFriend, const std::string &uriOrTel, const std::shared_ptr &presenceModel ) override; void onNotifyPresenceReceived ( const std::shared_ptr &core, const std::shared_ptr &linphoneFriend ) override; void onRegistrationStateChanged ( const std::shared_ptr &core, const std::shared_ptr &proxyConfig, linphone::RegistrationState state, const std::string &message ) override; void onTransferStateChanged ( const std::shared_ptr &core, const std::shared_ptr &call, linphone::Call::State state ) override; void onVersionUpdateCheckResultReceived ( const std::shared_ptr &, linphone::VersionUpdateCheckResult result, const std::string &version, const std::string &url ) override; // --------------------------------------------------------------------------- bool mCoreCreated = false; bool mCoreStarted = false; QMutex *mCoreStartedLock = nullptr; }; #endif // CORE_HANDLERS_H_ linphone-desktop-4.2.5/linphone-app/src/components/core/CoreManager.cpp000066400000000000000000000307251376717241300262140ustar00rootroot00000000000000/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include #include #include #include #include #include #include "config.h" #include "app/paths/Paths.hpp" #include "components/calls/CallsListModel.hpp" #include "components/chat/ChatModel.hpp" #include "components/contact/VcardModel.hpp" #include "components/contacts/ContactsListModel.hpp" #include "components/history/HistoryModel.hpp" #include "components/settings/AccountSettingsModel.hpp" #include "components/settings/SettingsModel.hpp" #include "components/sip-addresses/SipAddressesModel.hpp" #include "utils/Utils.hpp" #if defined(Q_OS_MACOS) #include "event-count-notifier/EventCountNotifierMacOs.hpp" #else #include "event-count-notifier/EventCountNotifierSystemTrayIcon.hpp" #endif // if defined(Q_OS_MACOS) #include "CoreHandlers.hpp" #include "CoreManager.hpp" #include // ============================================================================= using namespace std; namespace { constexpr int CbsCallInterval = 20; constexpr char RcVersionName[] = "rc_version"; constexpr int RcVersionCurrent = 1; // TODO: Remove hardcoded values. Use config directly. constexpr char LinphoneDomain[] = "sip.linphone.org"; constexpr char DefaultContactParameters[] = "message-expires=604800"; constexpr int DefaultExpires = 3600; constexpr char DownloadUrl[] = "https://www.linphone.org/technical-corner/linphone"; } // ----------------------------------------------------------------------------- CoreManager *CoreManager::mInstance; CoreManager::CoreManager (QObject *parent, const QString &configPath) : QObject(parent), mHandlers(make_shared(this)) { QTimer * delayedCreationTimer = new QTimer(); delayedCreationTimer->setSingleShot(true); QObject::connect(delayedCreationTimer, &QTimer::timeout, this , [configPath, this, delayedCreationTimer]{ delayedCreationTimer->deleteLater(); createLinphoneCore(configPath); qInfo() << QStringLiteral("Core created. Enable iterate."); mInstance->mCbsTimer->start(); emit mInstance->coreCreated(); }); CoreHandlers *coreHandlers = mHandlers.get(); QObject::connect(coreHandlers, &CoreHandlers::coreStarted, this, [] { // Do not change this order. :) (Or pray.) mInstance->mCallsListModel = new CallsListModel(mInstance); mInstance->mContactsListModel = new ContactsListModel(mInstance); mInstance->mAccountSettingsModel = new AccountSettingsModel(mInstance); mInstance->mSettingsModel = new SettingsModel(mInstance); mInstance->mSipAddressesModel = new SipAddressesModel(mInstance); EventCountNotifier *eventCountNotifier = new EventCountNotifier(mInstance); eventCountNotifier->updateUnreadMessageCount(); QObject::connect(eventCountNotifier, &EventCountNotifier::eventCountChanged, mInstance, &CoreManager::eventCountChanged ); mInstance->mEventCountNotifier = eventCountNotifier; mInstance->migrate(); mInstance->mStarted = true; emit mInstance->coreStarted(); }); QObject::connect(coreHandlers, &CoreHandlers::logsUploadStateChanged, this, &CoreManager::handleLogsUploadStateChanged); delayedCreationTimer->start(CbsCallInterval); } // ----------------------------------------------------------------------------- shared_ptr CoreManager::getChatModel (const QString &peerAddress, const QString &localAddress) { if (peerAddress.isEmpty() || localAddress.isEmpty()) return nullptr; // Create a new chat model. QPair chatModelId{ peerAddress, localAddress }; if (!mChatModels.contains(chatModelId)) { if ( !mCore->createAddress(Utils::appStringToCoreString(peerAddress)) || !mCore->createAddress(Utils::appStringToCoreString(localAddress)) ) { qWarning() << QStringLiteral("Unable to get chat model from invalid chat model id: (%1, %2).") .arg(peerAddress).arg(localAddress); return nullptr; } auto deleter = [this, chatModelId](ChatModel *chatModel) { bool removed = mChatModels.remove(chatModelId); Q_ASSERT(removed); delete chatModel; }; shared_ptr chatModel(new ChatModel(peerAddress, localAddress), deleter); mChatModels[chatModelId] = chatModel; emit chatModelCreated(chatModel); return chatModel; } // Returns an existing chat model. shared_ptr chatModel = mChatModels[chatModelId].lock(); Q_CHECK_PTR(chatModel); return chatModel; } bool CoreManager::chatModelExists (const QString &peerAddress, const QString &localAddress) { return mChatModels.contains({ peerAddress, localAddress }); } HistoryModel* CoreManager::getHistoryModel(){ if(!mHistoryModel){ mHistoryModel = new HistoryModel(this); emit historyModelCreated(mHistoryModel); } return mHistoryModel; } // ----------------------------------------------------------------------------- void CoreManager::init (QObject *parent, const QString &configPath) { if (mInstance) return; mInstance = new CoreManager(parent, configPath); QTimer *timer = mInstance->mCbsTimer = new QTimer(mInstance); timer->setInterval(CbsCallInterval); QObject::connect(timer, &QTimer::timeout, mInstance, &CoreManager::iterate); } void CoreManager::uninit () { if (mInstance) { delete mInstance; mInstance = nullptr; } } // ----------------------------------------------------------------------------- VcardModel *CoreManager::createDetachedVcardModel () const { VcardModel *vcardModel = new VcardModel(linphone::Factory::get()->createVcard(), false); qInfo() << QStringLiteral("Create detached vcard:") << vcardModel; return vcardModel; } void CoreManager::forceRefreshRegisters () { Q_CHECK_PTR(mCore); qInfo() << QStringLiteral("Refresh registers."); mCore->refreshRegisters(); } // ----------------------------------------------------------------------------- void CoreManager::sendLogs () const { Q_CHECK_PTR(mCore); qInfo() << QStringLiteral("Send logs to: `%1` from `%2`.") .arg(Utils::coreStringToAppString(mCore->getLogCollectionUploadServerUrl())) .arg(Utils::coreStringToAppString(mCore->getLogCollectionPath())); mCore->uploadLogCollection(); } void CoreManager::cleanLogs () const { Q_CHECK_PTR(mCore); mCore->resetLogCollection(); } // ----------------------------------------------------------------------------- #define SET_DATABASE_PATH(DATABASE, PATH) \ do { \ qInfo() << QStringLiteral("Set `%1` path: `%2`") \ .arg( # DATABASE) \ .arg(Utils::coreStringToAppString(PATH)); \ mCore->set ## DATABASE ## DatabasePath(PATH); \ } while (0); void CoreManager::setDatabasesPaths () { SET_DATABASE_PATH(Friends, Paths::getFriendsListFilePath()); SET_DATABASE_PATH(CallLogs, Paths::getCallHistoryFilePath()); if(QFile::exists(Utils::coreStringToAppString(Paths::getMessageHistoryFilePath()))){ linphone_core_set_chat_database_path(mCore->cPtr(), Paths::getMessageHistoryFilePath().c_str()); //SET_DATABASE_PATH(Chat, Paths::getMessageHistoryFilePath());// Setting the message database let SDK to migrate data QFile::remove(Utils::coreStringToAppString(Paths::getMessageHistoryFilePath())); } } #undef SET_DATABASE_PATH // ----------------------------------------------------------------------------- void CoreManager::setOtherPaths () { if (mCore->getZrtpSecretsFile().empty() || !Paths::filePathExists(mCore->getZrtpSecretsFile())) mCore->setZrtpSecretsFile(Paths::getZrtpSecretsFilePath()); if (mCore->getUserCertificatesPath().empty() || !Paths::filePathExists(mCore->getUserCertificatesPath())) mCore->setUserCertificatesPath(Paths::getUserCertificatesDirPath()); if (mCore->getRootCa().empty() || !Paths::filePathExists(mCore->getRootCa())) mCore->setRootCa(Paths::getRootCaFilePath()); } void CoreManager::setResourcesPaths () { shared_ptr factory = linphone::Factory::get(); factory->setMspluginsDir(Paths::getPackageMsPluginsDirPath()); factory->setTopResourcesDir(Paths::getPackageDataDirPath()); } // ----------------------------------------------------------------------------- void CoreManager::createLinphoneCore (const QString &configPath) { qInfo() << QStringLiteral("Launch async core creation."); // Migration of configuration and database files from GTK version of Linphone. Paths::migrate(); setResourcesPaths(); mCore = linphone::Factory::get()->createCore( Paths::getConfigFilePath(configPath), Paths::getFactoryConfigFilePath(), nullptr ); mCore->addListener(mHandlers); mCore->setVideoDisplayFilter("MSOGL"); mCore->usePreviewWindow(true); mCore->enableVideoPreview(false); mCore->setUserAgent( Utils::appStringToCoreString( QStringLiteral(APPLICATION_NAME" Desktop/%1 (%2, Qt %3) LinphoneCore") .arg(QCoreApplication::applicationVersion()) .arg(QSysInfo::prettyProductName()) .arg(qVersion()) ), mCore->getVersion() ); // Force capture/display. // Useful if the app was built without video support. // (The capture/display attributes are reset by the core in this case.) if (mCore->videoSupported()) { shared_ptr config = mCore->getConfig(); config->setInt("video", "capture", 1); config->setInt("video", "display", 1); } mCore->start(); setDatabasesPaths(); setOtherPaths(); mCore->enableFriendListSubscription(true); } void CoreManager::migrate () { shared_ptr config = mCore->getConfig(); int rcVersion = config->getInt(SettingsModel::UiSection, RcVersionName, 0); if (rcVersion == RcVersionCurrent) return; if (rcVersion > RcVersionCurrent) { qWarning() << QStringLiteral("RC file version (%1) is more recent than app rc file version (%2)!!!") .arg(rcVersion).arg(RcVersionCurrent); return; } qInfo() << QStringLiteral("Migrate from old rc file (%1 to %2).") .arg(rcVersion).arg(RcVersionCurrent); // Add message_expires param on old proxy configs. for (const auto &proxyConfig : mCore->getProxyConfigList()) { if (proxyConfig->getDomain() == LinphoneDomain) { proxyConfig->setContactParameters(DefaultContactParameters); proxyConfig->setExpires(DefaultExpires); proxyConfig->done(); } } config->setInt(SettingsModel::UiSection, RcVersionName, RcVersionCurrent); } // ----------------------------------------------------------------------------- QString CoreManager::getVersion () const { return Utils::coreStringToAppString(mCore->getVersion()); } // ----------------------------------------------------------------------------- int CoreManager::getEventCount () const { return mEventCountNotifier ? mEventCountNotifier->getEventCount() : 0; } int CoreManager::getMissedCallCount(const QString &peerAddress, const QString &localAddress)const{ return mEventCountNotifier ? mEventCountNotifier->getMissedCallCount(peerAddress, localAddress) : 0; } int CoreManager::getMissedCallCountFromLocal( const QString &localAddress)const{ return mEventCountNotifier ? mEventCountNotifier->getMissedCallCountFromLocal(localAddress) : 0; } // ----------------------------------------------------------------------------- void CoreManager::iterate () { mInstance->lockVideoRender(); mCore->iterate(); mInstance->unlockVideoRender(); } // ----------------------------------------------------------------------------- void CoreManager::handleLogsUploadStateChanged (linphone::Core::LogCollectionUploadState state, const string &info) { switch (state) { case linphone::Core::LogCollectionUploadState::InProgress: break; case linphone::Core::LogCollectionUploadState::Delivered: case linphone::Core::LogCollectionUploadState::NotDelivered: emit logsUploaded(Utils::coreStringToAppString(info)); break; } } // ----------------------------------------------------------------------------- QString CoreManager::getDownloadUrl () { return DownloadUrl; } linphone-desktop-4.2.5/linphone-app/src/components/core/CoreManager.hpp000066400000000000000000000127011376717241300262130ustar00rootroot00000000000000/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef CORE_MANAGER_H_ #define CORE_MANAGER_H_ #include #include #include #include #include // ============================================================================= class QTimer; class AccountSettingsModel; class CallsListModel; class ChatModel; class ContactsListModel; class CoreHandlers; class EventCountNotifier; class HistoryModel; class SettingsModel; class SipAddressesModel; class VcardModel; class CoreManager : public QObject { Q_OBJECT; Q_PROPERTY(QString version READ getVersion CONSTANT) Q_PROPERTY(QString downloadUrl READ getDownloadUrl CONSTANT) Q_PROPERTY(int eventCount READ getEventCount NOTIFY eventCountChanged) public: bool started () const { return mStarted; } std::shared_ptr getCore () { Q_CHECK_PTR(mCore); return mCore; } std::shared_ptr getHandlers () { Q_CHECK_PTR(mHandlers); return mHandlers; } std::shared_ptr getChatModel (const QString &peerAddress, const QString &localAddress); bool chatModelExists (const QString &sipAddress, const QString &localAddress); HistoryModel* getHistoryModel(); // --------------------------------------------------------------------------- // Video render lock. // --------------------------------------------------------------------------- void lockVideoRender () { mMutexVideoRender.lock(); } void unlockVideoRender () { mMutexVideoRender.unlock(); } // --------------------------------------------------------------------------- // Singleton models. // --------------------------------------------------------------------------- CallsListModel *getCallsListModel () const { Q_CHECK_PTR(mCallsListModel); return mCallsListModel; } ContactsListModel *getContactsListModel () const { Q_CHECK_PTR(mContactsListModel); return mContactsListModel; } SipAddressesModel *getSipAddressesModel () const { Q_CHECK_PTR(mSipAddressesModel); return mSipAddressesModel; } SettingsModel *getSettingsModel () const { Q_CHECK_PTR(mSettingsModel); return mSettingsModel; } AccountSettingsModel *getAccountSettingsModel () const { Q_CHECK_PTR(mAccountSettingsModel); return mAccountSettingsModel; } // --------------------------------------------------------------------------- // Initialization. // --------------------------------------------------------------------------- static void init (QObject *parent, const QString &configPath); static void uninit (); static CoreManager *getInstance () { Q_CHECK_PTR(mInstance); return mInstance; } // --------------------------------------------------------------------------- // Must be used in a qml scene. // Warning: The ownership of `VcardModel` is `QQmlEngine::JavaScriptOwnership` by default. Q_INVOKABLE VcardModel *createDetachedVcardModel () const; Q_INVOKABLE void forceRefreshRegisters (); Q_INVOKABLE void sendLogs () const; Q_INVOKABLE void cleanLogs () const; int getMissedCallCount(const QString &peerAddress, const QString &localAddress) const;// Get missed call count from a chat (useful for showing bubbles on Timelines) int getMissedCallCountFromLocal(const QString &localAddress) const;// Get missed call count from a chat (useful for showing bubbles on Timelines) signals: void coreCreated (); void coreStarted (); void chatModelCreated (const std::shared_ptr &chatModel); void historyModelCreated (HistoryModel *historyModel); void logsUploaded (const QString &url); void eventCountChanged (int count); private: CoreManager (QObject *parent, const QString &configPath); void setDatabasesPaths (); void setOtherPaths (); void setResourcesPaths (); void createLinphoneCore (const QString &configPath); void migrate (); QString getVersion () const; int getEventCount () const; void iterate (); void handleLogsUploadStateChanged (linphone::Core::LogCollectionUploadState state, const std::string &info); static QString getDownloadUrl (); std::shared_ptr mCore; std::shared_ptr mHandlers; bool mStarted = false; CallsListModel *mCallsListModel = nullptr; ContactsListModel *mContactsListModel = nullptr; SipAddressesModel *mSipAddressesModel = nullptr; SettingsModel *mSettingsModel = nullptr; AccountSettingsModel *mAccountSettingsModel = nullptr; EventCountNotifier *mEventCountNotifier = nullptr; QHash, std::weak_ptr> mChatModels; HistoryModel * mHistoryModel = nullptr; QTimer *mCbsTimer = nullptr; QMutex mMutexVideoRender; static CoreManager *mInstance; }; #endif // CORE_MANAGER_H_ linphone-desktop-4.2.5/linphone-app/src/components/core/event-count-notifier/000077500000000000000000000000001376717241300274025ustar00rootroot00000000000000AbstractEventCountNotifier.cpp000066400000000000000000000120221376717241300353020ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/src/components/core/event-count-notifier/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include #include "components/call/CallModel.hpp" #include "components/calls/CallsListModel.hpp" #include "components/chat/ChatModel.hpp" #include "components/core/CoreHandlers.hpp" #include "components/core/CoreManager.hpp" #include "components/history/HistoryModel.hpp" #include "components/settings/SettingsModel.hpp" #include "utils/Utils.hpp" #include "AbstractEventCountNotifier.hpp" // ============================================================================= using namespace std; AbstractEventCountNotifier::AbstractEventCountNotifier (QObject *parent) : QObject(parent) { CoreManager *coreManager = CoreManager::getInstance(); QObject::connect( coreManager, &CoreManager::chatModelCreated, this, &AbstractEventCountNotifier::handleChatModelCreated ); QObject::connect( coreManager, &CoreManager::historyModelCreated, this, &AbstractEventCountNotifier::handleHistoryModelCreated ); QObject::connect( coreManager->getHandlers().get(), &CoreHandlers::messageReceived, this, &AbstractEventCountNotifier::updateUnreadMessageCount ); QObject::connect( coreManager->getSettingsModel(), &SettingsModel::chatEnabledChanged, this, &AbstractEventCountNotifier::internalnotifyEventCount ); QObject::connect( coreManager->getCallsListModel(), &CallsListModel::callMissed, this, &AbstractEventCountNotifier::handleCallMissed ); } // ----------------------------------------------------------------------------- void AbstractEventCountNotifier::updateUnreadMessageCount () { mUnreadMessageCount = CoreManager::getInstance()->getCore()->getUnreadChatMessageCountFromActiveLocals(); internalnotifyEventCount(); } void AbstractEventCountNotifier::internalnotifyEventCount () { int n = mUnreadMessageCount + getMissedCallCount(); qInfo() << QStringLiteral("Notify event count: %1.").arg(n); n = n > 99 ? 99 : n; notifyEventCount(CoreManager::getInstance()->getSettingsModel()->getChatEnabled() ? n : 0); emit eventCountChanged(n); } // Get missed call from a chat (useful for showing bubbles on Timelines) int AbstractEventCountNotifier::getMissedCallCount(const QString &peerAddress, const QString &localAddress) const{ auto it = mMissedCalls.find({ Utils::cleanSipAddress(peerAddress), Utils::cleanSipAddress(localAddress) }); if (it != mMissedCalls.cend()) return *it; else return 0; } // Get missed call from a chat (useful for showing bubbles on Timelines) int AbstractEventCountNotifier::getMissedCallCountFromLocal(const QString &localAddress) const{ QString cleanAddress = Utils::cleanSipAddress(localAddress); int count = 0; for(auto it = mMissedCalls.cbegin() ; it != mMissedCalls.cend() ; ++it){ if(it.key().second == cleanAddress) count += *it; } return count; } // ----------------------------------------------------------------------------- void AbstractEventCountNotifier::handleChatModelCreated (const shared_ptr &chatModel) { ChatModel *chatModelPtr = chatModel.get(); QObject::connect( chatModelPtr, &ChatModel::messageCountReset, this, &AbstractEventCountNotifier::updateUnreadMessageCount ); QObject::connect( chatModelPtr, &ChatModel::focused, this, [this, chatModelPtr]() { handleResetMissedCalls(chatModelPtr); } ); QObject::connect( chatModelPtr, &ChatModel::messageCountReset, this, [this, chatModelPtr]() { handleResetMissedCalls(chatModelPtr); } ); } void AbstractEventCountNotifier::handleHistoryModelCreated (HistoryModel *historyModel) { QObject::connect(historyModel, &HistoryModel::callCountReset , this, &AbstractEventCountNotifier::handleResetAllMissedCalls); } void AbstractEventCountNotifier::handleResetAllMissedCalls () { mMissedCalls.clear(); internalnotifyEventCount(); } void AbstractEventCountNotifier::handleResetMissedCalls (ChatModel *chatModel) { auto it = mMissedCalls.find({ Utils::cleanSipAddress(chatModel->getPeerAddress()), Utils::cleanSipAddress(chatModel->getLocalAddress()) }); if (it != mMissedCalls.cend()) { mMissedCalls.erase(it); internalnotifyEventCount(); } } void AbstractEventCountNotifier::handleCallMissed (CallModel *callModel) { ++mMissedCalls[{ Utils::cleanSipAddress(callModel->getPeerAddress()), Utils::cleanSipAddress(callModel->getLocalAddress()) }]; internalnotifyEventCount(); } AbstractEventCountNotifier.hpp000066400000000000000000000046671376717241300353270ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/src/components/core/event-count-notifier/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef ABSTRACT_EVENT_COUNT_NOTIFIER_H_ #define ABSTRACT_EVENT_COUNT_NOTIFIER_H_ #include #include #include #include // ============================================================================= namespace linphone { class ChatMessage; } class CallModel; class ChatModel; class HistoryModel; class AbstractEventCountNotifier : public QObject { Q_OBJECT; public: AbstractEventCountNotifier (QObject *parent = Q_NULLPTR); void updateUnreadMessageCount (); int getUnreadMessageCount () const { return mUnreadMessageCount; } int getMissedCallCount () const { int t = 0; for (int n : mMissedCalls) t += n; return t; } int getEventCount () const { return mUnreadMessageCount + getMissedCallCount(); } int getMissedCallCount(const QString &peerAddress, const QString &localAddress) const;// Get missed call count from a chat (useful for showing bubbles on Timelines) int getMissedCallCountFromLocal(const QString &localAddress) const;// Get missed call count from a chat (useful for showing bubbles on Timelines) signals: void eventCountChanged (int count); protected: virtual void notifyEventCount (int n) = 0; private: using ConferenceId = QPair; void internalnotifyEventCount (); void handleChatModelCreated (const std::shared_ptr &chatModel); void handleHistoryModelCreated (HistoryModel *historyModel); void handleResetAllMissedCalls (); void handleResetMissedCalls (ChatModel *chatModel); void handleCallMissed (CallModel *callModel); QHash mMissedCalls; int mUnreadMessageCount = 0; }; #endif // ABSTRACT_EVENT_COUNT_NOTIFIER_H_ EventCountNotifierMacOs.hpp000066400000000000000000000024631376717241300345560ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/src/components/core/event-count-notifier/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef EVENT_COUNT_NOTIFIER_MAC_OS_H_ #define EVENT_COUNT_NOTIFIER_MAC_OS_H_ #include "AbstractEventCountNotifier.hpp" // ============================================================================= extern "C" void notifyEventCountMacOs (int n); class EventCountNotifier : public AbstractEventCountNotifier { public: EventCountNotifier (QObject *parent = Q_NULLPTR) : AbstractEventCountNotifier(parent) {} void notifyEventCount (int n) override { notifyEventCountMacOs(n); } }; #endif // EVENT_COUNT_NOTIFIER_MAC_OS_H_ EventCountNotifierMacOs.m000066400000000000000000000022111376717241300342120ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/src/components/core/event-count-notifier/* * EventCountNotifierMacOs.m * Copyright (C) 2017-2018 Belledonne Communications, Grenoble, France * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * Created on: June 30, 2017 * Author: Ghislain MARY */ #import // ============================================================================= void notifyEventCountMacOs (int n) { NSString *badgeStr = (n > 0) ? [NSString stringWithFormat:@"%d", n] : @""; [[NSApp dockTile] setBadgeLabel:badgeStr]; } EventCountNotifierSystemTrayIcon.cpp000066400000000000000000000067001376717241300365020ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/src/components/core/event-count-notifier/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include #include #include #include #include #include #include "app/App.hpp" #include "utils/LinphoneUtils.hpp" #include "utils/Utils.hpp" #include "EventCountNotifierSystemTrayIcon.hpp" // ============================================================================= namespace { constexpr int IconWidth = 256; constexpr int IconHeight = 256; constexpr char IconCounterBackgroundColor[] = "#FF3C31"; constexpr int IconCounterBackgroundRadius = 100; constexpr int IconCounterBlinkInterval = 1000; constexpr char IconCounterTextColor[] = "#FFFBFA"; constexpr int IconCounterTextPixelSize = 144; } EventCountNotifier::EventCountNotifier (QObject *parent) : AbstractEventCountNotifier(parent) { QSvgRenderer renderer((QString(LinphoneUtils::WindowIconPath))); if (!renderer.isValid()) qFatal("Invalid SVG Image."); QPixmap buf(IconWidth, IconHeight); buf.fill(QColor(Qt::transparent)); QPainter painter(&buf); renderer.render(&painter); mBuf = new QPixmap(buf); mBufWithCounter = new QPixmap(); mBlinkTimer = new QTimer(this); mBlinkTimer->setInterval(IconCounterBlinkInterval); QObject::connect(mBlinkTimer, &QTimer::timeout, this, &EventCountNotifier::update); Utils::connectOnce( App::getInstance(), &App::focusWindowChanged, this, &EventCountNotifier::updateUnreadMessageCount ); } EventCountNotifier::~EventCountNotifier () { delete mBuf; delete mBufWithCounter; } void EventCountNotifier::notifyEventCount (int n) { QSystemTrayIcon *sysTrayIcon = App::getInstance()->getSystemTrayIcon(); if (!sysTrayIcon) return; if (!n) { mBlinkTimer->stop(); sysTrayIcon->setIcon(QIcon(*mBuf)); return; } *mBufWithCounter = *mBuf; QPainter p(mBufWithCounter); const int width = mBufWithCounter->width(); const int height = mBufWithCounter->height(); // Draw background. { p.setBrush(QColor(IconCounterBackgroundColor)); p.drawEllipse(QPointF(width / 2, height / 2), IconCounterBackgroundRadius, IconCounterBackgroundRadius); } // Draw text. { QFont font = p.font(); font.setPixelSize(IconCounterTextPixelSize); p.setFont(font); p.setPen(QPen(QColor(IconCounterTextColor), 1)); p.drawText(QRect(0, 0, width, height), Qt::AlignCenter, QString::number(n)); } // Change counter. mBlinkTimer->stop(); mBlinkTimer->start(); mDisplayCounter = true; update(); } void EventCountNotifier::update () { QSystemTrayIcon *sysTrayIcon = App::getInstance()->getSystemTrayIcon(); Q_CHECK_PTR(sysTrayIcon); sysTrayIcon->setIcon(QIcon(mDisplayCounter ? *mBufWithCounter : *mBuf)); mDisplayCounter = !mDisplayCounter; } EventCountNotifierSystemTrayIcon.hpp000066400000000000000000000026601376717241300365100ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/src/components/core/event-count-notifier/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef EVENT_COUNT_NOTIFIER_SYSTEM_TRAY_ICON_H_ #define EVENT_COUNT_NOTIFIER_SYSTEM_TRAY_ICON_H_ #include "AbstractEventCountNotifier.hpp" // ============================================================================= class QTimer; class EventCountNotifier : public AbstractEventCountNotifier { public: EventCountNotifier (QObject *parent = Q_NULLPTR); ~EventCountNotifier (); protected: void notifyEventCount (int n) override; private: void update (); const QPixmap *mBuf = nullptr; QPixmap *mBufWithCounter = nullptr; QTimer *mBlinkTimer = nullptr; bool mDisplayCounter = false; }; #endif // EVENT_COUNT_NOTIFIER_SYSTEM_TRAY_ICON_H_ linphone-desktop-4.2.5/linphone-app/src/components/file/000077500000000000000000000000001376717241300233055ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/src/components/file/FileDownloader.cpp000066400000000000000000000161101376717241300267060ustar00rootroot00000000000000/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "app/paths/Paths.hpp" #include "components/core/CoreManager.hpp" #include "components/settings/SettingsModel.hpp" #include "utils/Utils.hpp" #include "FileDownloader.hpp" // ============================================================================= namespace { constexpr char cDefaultFileName[] = "download"; } static QString getDownloadFilePath (const QString &folder, const QUrl &url) { QFileInfo fileInfo(url.path()); QString fileName = fileInfo.fileName(); if (fileName.isEmpty()) fileName = cDefaultFileName; fileName.prepend(folder); if (!QFile::exists(fileName)) return fileName; // Already exists, don't overwrite. QString baseName = fileInfo.completeBaseName(); if (baseName.isEmpty()) baseName = cDefaultFileName; QString suffix = fileInfo.suffix(); if (!suffix.isEmpty()) suffix.prepend("."); for (int i = 1; true; ++i) { fileName = folder + baseName + "(" + QString::number(i) + ")" + suffix; if (!QFile::exists(fileName)) break; } return fileName; } static bool isHttpRedirect (QNetworkReply *reply) { Q_CHECK_PTR(reply); int statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); return statusCode == 301 || statusCode == 302 || statusCode == 303 || statusCode == 305 || statusCode == 307 || statusCode == 308; } // ----------------------------------------------------------------------------- void FileDownloader::download () { if (mDownloading) { qWarning() << "Unable to download file. Already downloading!"; return; } setDownloading(true); QNetworkRequest request(mUrl); mNetworkReply = mManager.get(request); QNetworkReply *data = mNetworkReply.data(); QObject::connect(data, &QNetworkReply::readyRead, this, &FileDownloader::handleReadyData); QObject::connect(data, &QNetworkReply::finished, this, &FileDownloader::handleDownloadFinished); QObject::connect(data, QNonConstOverload::of(&QNetworkReply::error), this, &FileDownloader::handleError); QObject::connect(data, &QNetworkReply::downloadProgress, this, &FileDownloader::handleDownloadProgress); #if QT_CONFIG(ssl) QObject::connect(data, &QNetworkReply::sslErrors, this, &FileDownloader::handleSslErrors); #endif if (mDownloadFolder.isEmpty()) { mDownloadFolder = CoreManager::getInstance()->getSettingsModel()->getDownloadFolder(); emit downloadFolderChanged(mDownloadFolder); } Q_ASSERT(!mDestinationFile.isOpen()); mDestinationFile.setFileName(getDownloadFilePath(QDir::cleanPath(mDownloadFolder) + QDir::separator(), mUrl)); if (!mDestinationFile.open(QIODevice::WriteOnly)) emitOutputError(); else { mTimeoutReadBytes = 0; mTimeout.start(); } } bool FileDownloader::remove () { return mDestinationFile.exists() && !mDestinationFile.isOpen() && mDestinationFile.remove(); } void FileDownloader::emitOutputError () { qWarning() << QStringLiteral("Could not write into `%1` (%2).") .arg(mDestinationFile.fileName()).arg(mDestinationFile.errorString()); mNetworkReply->abort(); } void FileDownloader::cleanDownloadEnd () { mTimeout.stop(); mNetworkReply->deleteLater(); setDownloading(false); } void FileDownloader::handleReadyData () { QByteArray data = mNetworkReply->readAll(); if (mDestinationFile.write(data) == -1) emitOutputError(); } void FileDownloader::handleDownloadFinished() { if (mNetworkReply->error() != QNetworkReply::NoError) return; // TODO: Deal with redirection. if (isHttpRedirect(mNetworkReply)) { qWarning() << QStringLiteral("Request was redirected."); mDestinationFile.remove(); cleanDownloadEnd(); emit downloadFailed(); } else { qInfo() << QStringLiteral("Download of %1 finished to %2").arg(mUrl.toString(), mDestinationFile.fileName()); mDestinationFile.close(); cleanDownloadEnd(); emit downloadFinished(mDestinationFile.fileName()); } } void FileDownloader::handleError (QNetworkReply::NetworkError code) { if (code != QNetworkReply::OperationCanceledError) qWarning() << QStringLiteral("Download of %1 failed: %2") .arg(mUrl.toString()).arg(mNetworkReply->errorString()); mDestinationFile.remove(); cleanDownloadEnd(); emit downloadFailed(); } void FileDownloader::handleSslErrors (const QList &sslErrors) { #if QT_CONFIG(ssl) for (const QSslError &error : sslErrors) qWarning() << QStringLiteral("SSL error: %1").arg(error.errorString()); #else Q_UNUSED(sslErrors); #endif } void FileDownloader::handleTimeout () { if (mReadBytes == mTimeoutReadBytes) { qWarning() << QStringLiteral("Download of %1 failed: timeout.").arg(mUrl.toString()); mNetworkReply->abort(); } else mTimeoutReadBytes = mReadBytes; } void FileDownloader::handleDownloadProgress (qint64 readBytes, qint64 totalBytes) { setReadBytes(readBytes); setTotalBytes(totalBytes); } // ----------------------------------------------------------------------------- QUrl FileDownloader::getUrl () const { return mUrl; } void FileDownloader::setUrl (const QUrl &url) { if (mDownloading) { qWarning() << QStringLiteral("Unable to set url, a file is downloading."); return; } if (mUrl != url) { mUrl = url; emit urlChanged(mUrl); } } QString FileDownloader::getDownloadFolder () const { return mDownloadFolder; } void FileDownloader::setDownloadFolder (const QString &downloadFolder) { if (mDownloading) { qWarning() << QStringLiteral("Unable to set download folder, a file is downloading."); return; } if (mDownloadFolder != downloadFolder) { mDownloadFolder = downloadFolder; emit downloadFolderChanged(mDownloadFolder); } } qint64 FileDownloader::getReadBytes () const { return mReadBytes; } void FileDownloader::setReadBytes (qint64 readBytes) { if (mReadBytes != readBytes) { mReadBytes = readBytes; emit readBytesChanged(readBytes); } } qint64 FileDownloader::getTotalBytes () const { return mTotalBytes; } void FileDownloader::setTotalBytes (qint64 totalBytes) { if (mTotalBytes != totalBytes) { mTotalBytes = totalBytes; emit totalBytesChanged(totalBytes); } } bool FileDownloader::getDownloading () const { return mDownloading; } void FileDownloader::setDownloading (bool downloading) { if (mDownloading != downloading) { mDownloading = downloading; emit downloadingChanged(downloading); } } linphone-desktop-4.2.5/linphone-app/src/components/file/FileDownloader.hpp000066400000000000000000000063261376717241300267230ustar00rootroot00000000000000/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef FILE_DOWNLOADER_H_ #define FILE_DOWNLOADER_H_ #include #include // ============================================================================= class QSslError; class FileDownloader : public QObject { Q_OBJECT; // TODO: Add an error property to use in UI. Q_PROPERTY(QUrl url READ getUrl WRITE setUrl NOTIFY urlChanged); Q_PROPERTY(QString downloadFolder READ getDownloadFolder WRITE setDownloadFolder NOTIFY downloadFolderChanged); Q_PROPERTY(qint64 readBytes READ getReadBytes NOTIFY readBytesChanged); Q_PROPERTY(qint64 totalBytes READ getTotalBytes NOTIFY totalBytesChanged); Q_PROPERTY(bool downloading READ getDownloading NOTIFY downloadingChanged); public: FileDownloader (QObject *parent = Q_NULLPTR) : QObject(parent) { // See: https://bugreports.qt.io/browse/QTBUG-57390 mTimeout.setInterval(DefaultTimeout); QObject::connect(&mTimeout, &QTimer::timeout, this, &FileDownloader::handleTimeout); } ~FileDownloader () { if (mNetworkReply) mNetworkReply->abort(); } Q_INVOKABLE void download (); Q_INVOKABLE bool remove(); QUrl getUrl () const; void setUrl (const QUrl &url); QString getDownloadFolder () const; void setDownloadFolder (const QString &downloadFolder); signals: void urlChanged (const QUrl &url); void downloadFolderChanged (const QString &downloadFolder); void readBytesChanged (qint64 readBytes); void totalBytesChanged (qint64 totalBytes); void downloadingChanged (bool downloading); void downloadFinished (const QString &filePath); void downloadFailed(); private: qint64 getReadBytes () const; void setReadBytes (qint64 readBytes); qint64 getTotalBytes () const; void setTotalBytes (qint64 totalBytes); bool getDownloading () const; void setDownloading (bool downloading); void emitOutputError (); void cleanDownloadEnd (); void handleReadyData (); void handleDownloadFinished (); void handleError (QNetworkReply::NetworkError code); void handleSslErrors (const QList &errors); void handleTimeout (); void handleDownloadProgress (qint64 readBytes, qint64 totalBytes); QUrl mUrl; QString mDownloadFolder; QFile mDestinationFile; qint64 mReadBytes = 0; qint64 mTotalBytes = 0; bool mDownloading = false; QPointer mNetworkReply; QNetworkAccessManager mManager; qint64 mTimeoutReadBytes; QTimer mTimeout; static constexpr int DefaultTimeout = 5000; }; #endif // FILE_DOWNLOADER_H_ linphone-desktop-4.2.5/linphone-app/src/components/file/FileExtractor.cpp000066400000000000000000000152451376717241300265730ustar00rootroot00000000000000/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include #include #include #include #include "FileExtractor.hpp" #include "FileDownloader.hpp" #include "app/paths/Paths.hpp" #include "utils/Utils.hpp" // ============================================================================= using namespace std; constexpr char LinphoneBZip2_exe[] = "http://www.linphone.org/releases/windows/tools/bzip2/bzip2.exe"; constexpr char LinphoneBZip2_dll[] = "http://www.linphone.org/releases/windows/tools/bzip2/bzip2.dll"; FileExtractor::FileExtractor (QObject *parent) : QObject(parent) {} FileExtractor::~FileExtractor () {} void FileExtractor::extract () { if (mExtracting) { qWarning() << "Unable to extract file. Already extracting!"; return; } setExtracting(true); QFileInfo fileInfo(mFile); if(!fileInfo.isReadable()){ emitExtractFailed(-1); return; } mDestinationFile = QDir::cleanPath(mExtractFolder) + QDir::separator() + (mExtractName.isEmpty() ? fileInfo.completeBaseName() : mExtractName); if(QFile::exists(mDestinationFile) && !QFile::remove(mDestinationFile)){ emitOutputError(); return; } if( mTimer == nullptr){ mTimer = new QTimer(this); QObject::connect(mTimer, &QTimer::timeout, this, &FileExtractor::handleExtraction); } #ifdef WIN32 // Test the presence of bzip2 in the system int result = QProcess::execute("bzip2.exe", QStringList()); if( result != -2 || QProcess::execute(Utils::coreStringToAppString(Paths::getToolsDirPath())+"\\bzip2.exe", QStringList())!=-2){ mTimer->start(); }else{// Download bzip2 QTimer * timer = mTimer; FileDownloader * fileDownloader = new FileDownloader(); int downloadStep = 0; fileDownloader->setUrl(QUrl(LinphoneBZip2_exe)); fileDownloader->setDownloadFolder(Utils::coreStringToAppString(Paths::getToolsDirPath())); QObject::connect(fileDownloader, &FileDownloader::totalBytesChanged, this, &FileExtractor::setTotalBytes); QObject::connect(fileDownloader, &FileDownloader::readBytesChanged, this, &FileExtractor::setReadBytes); QObject::connect(fileDownloader, &FileDownloader::downloadFinished, [fileDownloader, timer, downloadStep ]()mutable { if( downloadStep++ == 0){ fileDownloader->setUrl(QUrl(LinphoneBZip2_dll)); fileDownloader->download(); }else { fileDownloader->deleteLater(); timer->start(); } }); QObject::connect(fileDownloader, &FileDownloader::downloadFailed, [fileDownloader, this]() { fileDownloader->deleteLater(); emitExtractorFailed(); }); fileDownloader->download(); } #else mTimer->start(); #endif } bool FileExtractor::remove () { return QFile::exists(mDestinationFile) && QFile::remove(mDestinationFile); } QString FileExtractor::getFile () const { return mFile; } void FileExtractor::setFile (const QString &file) { if (mExtracting) { qWarning() << QStringLiteral("Unable to set file, a file is extracting."); return; } if (mFile != file) { mFile = file; emit fileChanged(mFile); } } QString FileExtractor::getExtractFolder () const { return mExtractFolder; } void FileExtractor::setExtractFolder (const QString &extractFolder) { if (mExtracting) { qWarning() << QStringLiteral("Unable to set extract folder, a file is extracting."); return; } if (mExtractFolder != extractFolder) { mExtractFolder = extractFolder; emit extractFolderChanged(mExtractFolder); } } QString FileExtractor::getExtractName () const { return mExtractName; } void FileExtractor::setExtractName (const QString &extractName) { if (mExtracting) { qWarning() << QStringLiteral("Unable to set extract name, a file is extracting."); return; } if (mExtractName != extractName) { mExtractName = extractName; emit extractNameChanged(mExtractName); } } bool FileExtractor::getExtracting () const { return mExtracting; } void FileExtractor::setExtracting (bool extracting) { if (mExtracting != extracting) { mExtracting = extracting; emit extractingChanged(extracting); } } qint64 FileExtractor::getReadBytes () const { return mReadBytes; } void FileExtractor::setReadBytes (qint64 readBytes) { if (mReadBytes != readBytes) { mReadBytes = readBytes; emit readBytesChanged(readBytes); } } qint64 FileExtractor::getTotalBytes () const { return mTotalBytes; } void FileExtractor::setTotalBytes (qint64 totalBytes) { if (mTotalBytes != totalBytes) { mTotalBytes = totalBytes; emit totalBytesChanged(totalBytes); } } void FileExtractor::clean () { if (mTimer) { mTimer->stop(); mTimer->deleteLater(); mTimer = nullptr; } setExtracting(false); } void FileExtractor::emitExtractorFailed () { qWarning() << QStringLiteral("Unable to extract file `%1`. bzip2 is unavailable, please install it.") .arg(mFile); clean(); emit extractFailed(); } void FileExtractor::emitExtractFailed (int error) { qWarning() << QStringLiteral("Unable to extract file with bzip2: `%1` (code: %2).") .arg(mFile).arg(error); clean(); emit extractFailed(); } void FileExtractor::emitExtractFinished () { clean(); emit extractFinished(); } void FileExtractor::emitOutputError () { qWarning() << QStringLiteral("Could not write into `%1`.") .arg(mDestinationFile); clean(); emit extractFailed(); } void FileExtractor::handleExtraction () { QString tempDestination = mDestinationFile+"."+QFileInfo(mFile).suffix(); QStringList args; args.push_back("-dq"); args.push_back(tempDestination); QFile::copy(mFile, tempDestination); #ifdef WIN32 int result = QProcess::execute("bzip2.exe", args); if( result == -2) result = QProcess::execute(Utils::coreStringToAppString(Paths::getToolsDirPath())+"\\bzip2.exe", args); #else int result = QProcess::execute("bzip2", args); #endif if(QFile::exists(tempDestination)) QFile::remove(tempDestination); if (result == 0) emitExtractFinished(); else if (result > 0) emitExtractFailed(result); else if(result == -2) emitExtractorFailed(); else emitOutputError(); } linphone-desktop-4.2.5/linphone-app/src/components/file/FileExtractor.hpp000066400000000000000000000057211376717241300265760ustar00rootroot00000000000000/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef FILE_EXTRACTOR_H_ #define FILE_EXTRACTOR_H_ #include // ============================================================================= class QTimer; // Supports only bzip file. class FileExtractor : public QObject { Q_OBJECT; // TODO: Add an error property to use in UI. Q_PROPERTY(QString file READ getFile WRITE setFile NOTIFY fileChanged); Q_PROPERTY(QString extractFolder READ getExtractFolder WRITE setExtractFolder NOTIFY extractFolderChanged); Q_PROPERTY(QString extractName READ getExtractName WRITE setExtractName NOTIFY extractNameChanged); Q_PROPERTY(bool extracting READ getExtracting NOTIFY extractingChanged); Q_PROPERTY(qint64 readBytes READ getReadBytes NOTIFY readBytesChanged); Q_PROPERTY(qint64 totalBytes READ getTotalBytes NOTIFY totalBytesChanged); public: FileExtractor (QObject *parent = nullptr); ~FileExtractor (); Q_INVOKABLE void extract (); Q_INVOKABLE bool remove (); QString getFile () const; void setFile (const QString &file); QString getExtractFolder () const; void setExtractFolder (const QString &extractFolder); QString getExtractName () const; void setExtractName (const QString &extractName); signals: void fileChanged (const QString &file); void extractFolderChanged (const QString &extractFolder); void extractNameChanged (const QString &extractName); void readBytesChanged (qint64 readBytes); void totalBytesChanged (qint64 totalBytes); void extractingChanged (bool extracting); void extractFinished (); void extractFailed (); private: qint64 getReadBytes () const; void setReadBytes (qint64 readBytes); qint64 getTotalBytes () const; void setTotalBytes (qint64 totalBytes); bool getExtracting () const; void setExtracting (bool extracting); void clean (); void emitExtractFinished (); void emitExtractorFailed (); // Used when bzip2 cannot be used void emitExtractFailed (int error); void emitOutputError (); void handleExtraction (); QString mFile; QString mExtractFolder; QString mExtractName; QString mDestinationFile; bool mExtracting = false; qint64 mReadBytes = 0; qint64 mTotalBytes = 0; QTimer *mTimer = nullptr; }; #endif // FILE_EXTRACTOR_H_ linphone-desktop-4.2.5/linphone-app/src/components/history/000077500000000000000000000000001376717241300240675ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/src/components/history/HistoryModel.cpp000066400000000000000000000173551376717241300272300ustar00rootroot00000000000000/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include #include #include #include #include #include #include #include #include #include #include #include "app/App.hpp" #include "app/paths/Paths.hpp" #include "app/providers/ThumbnailProvider.hpp" #include "components/core/CoreHandlers.hpp" #include "components/core/CoreManager.hpp" #include "components/notifier/Notifier.hpp" #include "components/settings/SettingsModel.hpp" #include "utils/QExifImageHeader.hpp" #include "utils/Utils.hpp" #include "HistoryModel.hpp" // ============================================================================= using namespace std; static inline void fillCallStartEntry (QVariantMap &dest, const shared_ptr &callLog) { dest["type"] = HistoryModel::CallEntry; dest["timestamp"] = QDateTime::fromMSecsSinceEpoch(callLog->getStartDate() * 1000); dest["isOutgoing"] = callLog->getDir() == linphone::Call::Dir::Outgoing; dest["status"] = static_cast(callLog->getStatus()); dest["isStart"] = true; dest["sipAddress"] = Utils::coreStringToAppString(callLog->getRemoteAddress()->asString()); } static inline void fillCallEndEntry (QVariantMap &dest, const shared_ptr &callLog) { dest["type"] = HistoryModel::CallEntry; dest["timestamp"] = QDateTime::fromMSecsSinceEpoch((callLog->getStartDate() + callLog->getDuration()) * 1000); dest["isOutgoing"] = callLog->getDir() == linphone::Call::Dir::Outgoing; dest["status"] = static_cast(callLog->getStatus()); dest["isStart"] = false; dest["sipAddress"] = Utils::coreStringToAppString(callLog->getRemoteAddress()->asString()); } // ----------------------------------------------------------------------------- HistoryModel::HistoryModel (QObject *parent) :QAbstractListModel(parent){ CoreManager *coreManager = CoreManager::getInstance(); mCoreHandlers = coreManager->getHandlers(); setSipAddresses(); CoreHandlers *coreHandlers = mCoreHandlers.get(); QObject::connect(coreHandlers, &CoreHandlers::callStateChanged, this, &HistoryModel::handleCallStateChanged); } HistoryModel::~HistoryModel () { } QHash HistoryModel::roleNames () const { QHash roles; roles[Roles::HistoryEntry] = "$historyEntry"; roles[Roles::SectionDate] = "$sectionDate"; return roles; } int HistoryModel::rowCount (const QModelIndex &) const { return mEntries.count(); } QVariant HistoryModel::data (const QModelIndex &index, int role) const { int row = index.row(); if (!index.isValid() || row < 0 || row >= mEntries.count()) return QVariant(); switch (role) { case Roles::HistoryEntry: { auto &data = mEntries[row].first; return QVariant::fromValue(data); } case Roles::SectionDate: return QVariant::fromValue(mEntries[row].first["timestamp"].toDate()); } return QVariant(); } bool HistoryModel::removeRow (int row, const QModelIndex &) { return removeRows(row, 1); } bool HistoryModel::removeRows (int row, int count, const QModelIndex &parent) { int limit = row + count - 1; if (row < 0 || count < 0 || limit >= mEntries.count()) return false; beginRemoveRows(parent, row, limit); for (int i = 0; i < count; ++i) { removeEntry(mEntries[row]); mEntries.removeAt(row); } endRemoveRows(); if (mEntries.count() == 0) emit allEntriesRemoved(); else if (limit == mEntries.count()) emit lastEntryRemoved(); emit focused();// Removing rows is like having focus. Don't wait asynchronous events. return true; } void HistoryModel::setSipAddresses () { shared_ptr core = CoreManager::getInstance()->getCore(); mEntries.clear(); QElapsedTimer timer; timer.start(); // Get calls. for (auto &callLog : core->getCallLogs()) insertCall(callLog); qInfo() << QStringLiteral("HistoryModel loaded in %3 milliseconds.").arg(timer.elapsed()); } // ----------------------------------------------------------------------------- void HistoryModel::removeEntry (int id) { qInfo() << QStringLiteral("Removing call entry: %1.").arg(id); if (!removeRow(id)) qWarning() << QStringLiteral("Unable to remove call entry: %1").arg(id); } void HistoryModel::removeAllEntries () { qInfo() << QStringLiteral("Removing all call entries."); beginResetModel(); for (auto &entry : mEntries) removeEntry(entry); mEntries.clear(); endResetModel(); emit allEntriesRemoved(); emit focused();// Removing all entries is like having focus. Don't wait asynchronous events. } // ----------------------------------------------------------------------------- void HistoryModel::removeEntry (HistoryEntryData &entry) { int type = entry.first["type"].toInt(); switch (type) { case HistoryModel::CallEntry: { if (entry.first["status"].toInt() == CallStatusSuccess) { // WARNING: Unable to remove symmetric call here. (start/end) // We are between `beginRemoveRows` and `endRemoveRows`. // A solution is to schedule a `removeEntry` call in the Qt main loop. shared_ptr linphonePtr = entry.second; QTimer::singleShot(0, this, [this, linphonePtr]() { auto it = find_if(mEntries.begin(), mEntries.end(), [linphonePtr](const HistoryEntryData &entry) { return entry.second == linphonePtr; }); if (it != mEntries.end()) removeEntry(int(distance(mEntries.begin(), it))); }); } CoreManager::getInstance()->getCore()->removeCallLog(static_pointer_cast(entry.second)); break; } default: qWarning() << QStringLiteral("Unknown history entry type: %1.").arg(type); } } void HistoryModel::insertCall (const shared_ptr &callLog) { linphone::Call::Status status = callLog->getStatus(); auto insertEntry = [this]( const HistoryEntryData &entry, const QList::iterator *start = nullptr ) { auto it = lower_bound(start ? *start : mEntries.begin(), mEntries.end(), entry, [](const HistoryEntryData &a, const HistoryEntryData &b) { return a.first["timestamp"] < b.first["timestamp"]; }); int row = int(distance(mEntries.begin(), it)); beginInsertRows(QModelIndex(), row, row); it = mEntries.insert(it, entry); endInsertRows(); return it; }; // Add start call. QVariantMap start; fillCallStartEntry(start, callLog); auto it = insertEntry(qMakePair(start, static_pointer_cast(callLog))); if (status == linphone::Call::Status::Success) { QVariantMap end; fillCallEndEntry(end, callLog); insertEntry(qMakePair(end, static_pointer_cast(callLog)), &it); } } // ----------------------------------------------------------------------------- void HistoryModel::resetMessageCount () { emit callCountReset(); } // ----------------------------------------------------------------------------- void HistoryModel::handleCallStateChanged (const shared_ptr &call, linphone::Call::State state) { if (state == linphone::Call::State::End || state == linphone::Call::State::Error) insertCall(call->getCallLog()); } linphone-desktop-4.2.5/linphone-app/src/components/history/HistoryModel.hpp000066400000000000000000000055601376717241300272300ustar00rootroot00000000000000/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef HISTORY_MODEL_H_ #define HISTORY_MODEL_H_ #include #include // ============================================================================= // Fetch all N messages of the History. // ============================================================================= class CoreHandlers; class HistoryModel : public QAbstractListModel { Q_OBJECT public: enum Roles { HistoryEntry = Qt::DisplayRole, SectionDate }; enum EntryType { GenericEntry, CallEntry }; Q_ENUM(EntryType) enum CallStatus { CallStatusDeclined = int(linphone::Call::Status::Declined), CallStatusMissed = int(linphone::Call::Status::Missed), CallStatusSuccess = int(linphone::Call::Status::Success), CallStatusAborted = int(linphone::Call::Status::Aborted), CallStatusEarlyAborted = int(linphone::Call::Status::EarlyAborted), CallStatusAcceptedElsewhere = int(linphone::Call::Status::AcceptedElsewhere), CallStatusDeclinedElsewhere = int(linphone::Call::Status::DeclinedElsewhere) }; Q_ENUM(CallStatus) HistoryModel (QObject *parent = Q_NULLPTR); virtual ~HistoryModel (); int rowCount (const QModelIndex &index = QModelIndex()) const override; QHash roleNames () const override; QVariant data (const QModelIndex &index, int role) const override; bool removeRow (int row, const QModelIndex &parent = QModelIndex()); bool removeRows (int row, int count, const QModelIndex &parent = QModelIndex()) override; void removeEntry (int id); void removeAllEntries (); void resetMessageCount (); signals: void allEntriesRemoved (); void lastEntryRemoved (); void focused (); void callCountReset(); private: typedef QPair> HistoryEntryData; void setSipAddresses (); void removeEntry (HistoryEntryData &entry); void insertCall (const std::shared_ptr &callLog); void handleCallStateChanged (const std::shared_ptr &call, linphone::Call::State state); mutable QList mEntries; std::shared_ptr mCoreHandlers; }; #endif // HISTORY_MODEL_H_ linphone-desktop-4.2.5/linphone-app/src/components/history/HistoryProxyModel.cpp000066400000000000000000000123131376717241300302570ustar00rootroot00000000000000/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include #include "app/App.hpp" #include "components/core/CoreManager.hpp" #include "HistoryProxyModel.hpp" #include "components/sip-addresses/SipAddressesModel.hpp" // ============================================================================= using namespace std; // Fetch the L last filtered history entries. class HistoryProxyModel::HistoryModelFilter : public QSortFilterProxyModel { public: HistoryModelFilter (QObject *parent) : QSortFilterProxyModel(parent) { } HistoryModel::EntryType getEntryTypeFilter () { return mEntryTypeFilter; } void setEntryTypeFilter (HistoryModel::EntryType type) { mEntryTypeFilter = type; invalidate(); } protected: bool filterAcceptsRow (int sourceRow, const QModelIndex &) const override { if (mEntryTypeFilter == HistoryModel::EntryType::GenericEntry) return true; QModelIndex index = sourceModel()->index(sourceRow, 0, QModelIndex()); const QVariantMap data = index.data().toMap(); return data["type"].toInt() == mEntryTypeFilter; } private: HistoryModel::EntryType mEntryTypeFilter = HistoryModel::EntryType::GenericEntry; }; // ============================================================================= HistoryProxyModel::HistoryProxyModel (QObject *parent) : QSortFilterProxyModel(parent) { setSourceModel(new HistoryModelFilter(this)); reload(); App *app = App::getInstance(); QObject::connect(app->getMainWindow(), &QWindow::activeChanged, this, [this]() { handleIsActiveChanged(App::getInstance()->getMainWindow()); }); QQuickWindow *callsWindow = app->getCallsWindow(); if (callsWindow) QObject::connect(callsWindow, &QWindow::activeChanged, this, [this, callsWindow]() { handleIsActiveChanged(callsWindow); }); } // ----------------------------------------------------------------------------- void HistoryProxyModel::removeAllEntries(){ auto model = CoreManager::getInstance()->getHistoryModel(); if (!model) return; model->removeAllEntries(); } void HistoryProxyModel::removeEntry (int id){ auto model = CoreManager::getInstance()->getHistoryModel(); if (!model) return; QModelIndex sourceIndex = mapToSource(index(id, 0)); model->removeEntry(static_cast(sourceModel())->mapToSource(sourceIndex).row() ); } // ----------------------------------------------------------------------------- void HistoryProxyModel::loadMoreEntries () { int count = rowCount(); int parentCount = sourceModel()->rowCount(); if (count < parentCount) { // Do not increase `mMaxDisplayedEntries` if it's not necessary... // Limit qml calls. if (count == mMaxDisplayedEntries) mMaxDisplayedEntries += EntriesChunkSize; invalidateFilter(); count = rowCount() - count; if (count > 0) emit moreEntriesLoaded(count); } } void HistoryProxyModel::setEntryTypeFilter (HistoryModel::EntryType type) { HistoryModelFilter *HistoryModelFilter = static_cast(sourceModel()); if (HistoryModelFilter->getEntryTypeFilter() != type) { HistoryModelFilter->setEntryTypeFilter(type); emit entryTypeFilterChanged(type); } } // ----------------------------------------------------------------------------- bool HistoryProxyModel::filterAcceptsRow (int sourceRow, const QModelIndex &) const { return sourceModel()->rowCount() - sourceRow <= mMaxDisplayedEntries; } // ----------------------------------------------------------------------------- void HistoryProxyModel::reload () { mMaxDisplayedEntries = EntriesChunkSize; static_cast(sourceModel())->setSourceModel(CoreManager::getInstance()->getHistoryModel()); } void HistoryProxyModel::resetMessageCount(){ auto model = CoreManager::getInstance()->getHistoryModel(); if( model){ model->resetMessageCount(); } } // ----------------------------------------------------------------------------- static inline QWindow *getParentWindow (QObject *object) { App *app = App::getInstance(); const QWindow *mainWindow = app->getMainWindow(); const QWindow *callsWindow = app->getCallsWindow(); for (QObject *parent = object->parent(); parent; parent = parent->parent()) if (parent == mainWindow || parent == callsWindow) return static_cast(parent); return nullptr; } void HistoryProxyModel::handleIsActiveChanged (QWindow *window) { auto model = CoreManager::getInstance()->getHistoryModel(); if (model && window->isActive() && getParentWindow(this) == window) { model->focused(); model->resetMessageCount(); } } linphone-desktop-4.2.5/linphone-app/src/components/history/HistoryProxyModel.hpp000066400000000000000000000035071376717241300302710ustar00rootroot00000000000000/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef HISTORY_PROXY_MODEL_H_ #define HISTORY_PROXY_MODEL_H_ #include #include "HistoryModel.hpp" // ============================================================================= class QWindow; class HistoryProxyModel : public QSortFilterProxyModel { class HistoryModelFilter; Q_OBJECT; public: HistoryProxyModel (QObject *parent = Q_NULLPTR); Q_INVOKABLE void loadMoreEntries (); Q_INVOKABLE void setEntryTypeFilter (HistoryModel::EntryType type = HistoryModel::EntryType::CallEntry); Q_INVOKABLE void removeEntry (int id); Q_INVOKABLE void removeAllEntries (); Q_INVOKABLE void resetMessageCount(); signals: void moreEntriesLoaded (int n); void entryTypeFilterChanged (HistoryModel::EntryType type); protected: bool filterAcceptsRow (int sourceRow, const QModelIndex &sourceParent) const override; private: void reload (); void handleIsActiveChanged (QWindow *window); int mMaxDisplayedEntries = EntriesChunkSize; static constexpr int EntriesChunkSize = 50; }; #endif // HISTORY_PROXY_MODEL_H_ linphone-desktop-4.2.5/linphone-app/src/components/notifier/000077500000000000000000000000001376717241300242055ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/src/components/notifier/Notifier.cpp000066400000000000000000000326541376717241300265020ustar00rootroot00000000000000/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include #include #include #include #include #include #include #include "app/App.hpp" #include "components/call/CallModel.hpp" #include "components/core/CoreManager.hpp" #include "utils/Utils.hpp" #include "Notifier.hpp" // ============================================================================= using namespace std; namespace { constexpr char NotificationsPath[] = "qrc:/ui/modules/Linphone/Notifications/"; // --------------------------------------------------------------------------- // Notifications QML properties/methods. // --------------------------------------------------------------------------- constexpr char NotificationShowMethodName[] = "open"; constexpr char NotificationPropertyData[] = "notificationData"; constexpr char NotificationPropertyX[] = "popupX"; constexpr char NotificationPropertyY[] = "popupY"; constexpr char NotificationPropertyWindow[] = "__internalWindow"; constexpr char NotificationPropertyTimer[] = "__timer"; // --------------------------------------------------------------------------- // Arbitrary hardcoded values. // --------------------------------------------------------------------------- constexpr int NotificationSpacing = 10; constexpr int MaxNotificationsNumber = 5; constexpr int MaxTimeout = 30000; } // ============================================================================= template void setProperty (QObject &object, const char *property, const T &value) { if (!object.setProperty(property, QVariant(value))) { qWarning() << QStringLiteral("Unable to set property: `%1`.").arg(property); abort(); } } // ============================================================================= // Available notifications. // ============================================================================= const QHash Notifier::Notifications = { { Notifier::ReceivedMessage, { "NotificationReceivedMessage.qml", 10 } }, { Notifier::ReceivedFileMessage, { "NotificationReceivedFileMessage.qml", 10 } }, { Notifier::ReceivedCall, { "NotificationReceivedCall.qml", 30 } }, { Notifier::NewVersionAvailable, { "NotificationNewVersionAvailable.qml", 30 } }, { Notifier::SnapshotWasTaken, { "NotificationSnapshotWasTaken.qml", 10 } }, { Notifier::RecordingCompleted, { "NotificationRecordingCompleted.qml", 10 } } }; // ----------------------------------------------------------------------------- Notifier::Notifier (QObject *parent) : QObject(parent) { const int nComponents = Notifications.size(); mComponents = new QQmlComponent *[nComponents]; QQmlEngine *engine = App::getInstance()->getEngine(); for (const auto &key : Notifications.keys()) { QQmlComponent *component = new QQmlComponent(engine, QUrl(NotificationsPath + Notifier::Notifications[key].filename)); if (Q_UNLIKELY(component->isError())) { qWarning() << QStringLiteral("Errors found in `Notification` component %1:").arg(key) << component->errors(); abort(); } mComponents[key] = component; } mMutex = new QMutex(); } Notifier::~Notifier () { delete mMutex; const int nComponents = Notifications.size(); for (int i = 0; i < nComponents; ++i) delete mComponents[i]; delete[] mComponents; } // ----------------------------------------------------------------------------- QObject *Notifier::createNotification (Notifier::NotificationType type, QVariantMap data) { QQuickItem *wrapperItem = nullptr; mMutex->lock(); Q_ASSERT(mInstancesNumber <= MaxNotificationsNumber); if (mInstancesNumber == MaxNotificationsNumber) { // Check existing instances. qWarning() << QStringLiteral("Unable to create another notification."); mMutex->unlock(); return nullptr; } QList allScreens = QGuiApplication::screens(); if(allScreens.size() > 0){ // Ensure to have a screen to avoid errors QQuickItem * previousWrapper = nullptr; ++mInstancesNumber; bool showAsTool = false; #ifdef Q_OS_MACOS for(auto w : QGuiApplication::topLevelWindows()){ if( (w->windowState()&Qt::WindowFullScreen)==Qt::WindowFullScreen){ showAsTool = true; w->raise();// Used to get focus on Mac (On Mac, A Tool is hidden if the app has not focus and the only way to rid it is to use Widget Attributes(Qt::WA_MacAlwaysShowToolWindow) that is not available) } } #endif for(int i = 0 ; i < allScreens.size() ; ++i){ QQuickView *view = new QQuickView(App::getInstance()->getEngine(), nullptr); // Use QQuickView to create a visual root object that is independant from current application Window QScreen *screen = allScreens[i]; QObject::connect(view, &QQuickView::statusChanged, [allScreens](QQuickView::Status status){ // Debug handler : show screens descriptions on Error if( status == QQuickView::Error){ QScreen * primaryScreen = QGuiApplication::primaryScreen(); qInfo() << "Primary screen : " << primaryScreen->geometry() << primaryScreen->availableGeometry() << primaryScreen->virtualGeometry() << primaryScreen->availableVirtualGeometry(); for(int i = 0 ; i < allScreens.size() ; ++i){ QScreen *screen = allScreens[i]; qInfo() << QString("Screen [")+QString::number(i)+"] (hdpi, Geometry, Available, Virtual, AvailableGeometry) :" << screen->devicePixelRatio() << screen->geometry() << screen->availableGeometry() << screen->virtualGeometry() << screen->availableVirtualGeometry(); } } }); view->setScreen(screen); // Bind the visual root object to the screen view->setProperty("flags", QVariant(Qt::BypassWindowManagerHint | Qt::WindowStaysOnBottomHint | Qt::CustomizeWindowHint | Qt::X11BypassWindowManagerHint)); // Set the visual ghost window view->setSource(QString(NotificationsPath)+Notifier::Notifications[type].filename); QQuickWindow *subWindow = view->findChild("__internalWindow"); QObject::connect(subWindow, &QObject::destroyed, view, &QObject::deleteLater); // When destroying window, detroy visual root object too int * screenHeightOffset = &mScreenHeightOffset[screen->name()]; // Access optimization QRect availableGeometry = screen->availableGeometry(); int heightOffset = availableGeometry.y() + (availableGeometry.height() - subWindow->height());//*screen->devicePixelRatio(); when using manual scaler if(showAsTool) subWindow->setProperty("showAsTool",true); subWindow->setX(availableGeometry.x()+ (availableGeometry.width()-subWindow->property("width").toInt()));//*screen->devicePixelRatio()); when using manual scaler subWindow->setY(heightOffset-(*screenHeightOffset % heightOffset)); *screenHeightOffset = (subWindow->height() + *screenHeightOffset) + NotificationSpacing; if (*screenHeightOffset - heightOffset + availableGeometry.y() >= 0) *screenHeightOffset = 0; // if(primaryScreen != screen){ //Useful when doing manual scaling jobs. Need to implement scaler in GUI objects // //subwindow->setProperty("xScale", (double)screen->availableVirtualGeometry().width()/availableGeometry.width() ); // //subwindow->setProperty("yScale", (double)screen->availableVirtualGeometry().height()/availableGeometry.height()); // } wrapperItem = view->findChild("__internalWrapper"); ::setProperty(*wrapperItem, NotificationPropertyData,data); view->setGeometry(subWindow->geometry()); // Ensure to have sufficient space to both let painter do job without error, and stay behind popup if(previousWrapper!=nullptr){ // Link objects in order to propagate events without having to store them QObject::connect(wrapperItem, SIGNAL(isOpened()), previousWrapper,SLOT(open())); QObject::connect(wrapperItem, SIGNAL(isClosed()), previousWrapper,SLOT(close())); QObject::connect(wrapperItem, &QObject::destroyed, previousWrapper, &QObject::deleteLater); } previousWrapper = wrapperItem; // The last one is used as a point of start when deleting and openning view->show(); } qInfo() << QStringLiteral("Create notifications:") << wrapperItem; } mMutex->unlock(); return wrapperItem; } // ----------------------------------------------------------------------------- void Notifier::showNotification (QObject *notification, int timeout) { // Display notification. QMetaObject::invokeMethod(notification, NotificationShowMethodName, Qt::DirectConnection); QTimer *timer = new QTimer(notification); timer->setInterval(timeout > MaxTimeout ? MaxTimeout : timeout); timer->setSingleShot(true); notification->setProperty(NotificationPropertyTimer, QVariant::fromValue(timer)); // Destroy it after timeout. QObject::connect(timer, &QTimer::timeout, this, [this, notification]() { deleteNotification(QVariant::fromValue(notification)); }); // Called explicitly (by a click on notification for example) QObject::connect(notification, SIGNAL(deleteNotification(QVariant)), this, SLOT(deleteNotification(QVariant))); timer->start(); } // ----------------------------------------------------------------------------- void Notifier::deleteNotification (QVariant notification) { mMutex->lock(); QObject *instance = notification.value(); // Notification marked destroyed. if (instance->property("__valid").isValid()) { mMutex->unlock(); return; } qInfo() << QStringLiteral("Delete notification:") << instance; instance->setProperty("__valid", true); instance->property(NotificationPropertyTimer).value()->stop(); mInstancesNumber--; Q_ASSERT(mInstancesNumber >= 0); if (mInstancesNumber == 0) mScreenHeightOffset.clear(); mMutex->unlock(); instance->deleteLater(); } // ============================================================================= #define CREATE_NOTIFICATION(TYPE, DATA) \ QObject * notification = createNotification(TYPE, DATA); \ if (!notification) \ return; \ const int timeout = Notifications[TYPE].timeout * 1000; \ showNotification(notification, timeout); // ----------------------------------------------------------------------------- // Notification functions. // ----------------------------------------------------------------------------- void Notifier::notifyReceivedMessage (const shared_ptr &message) { QVariantMap map; QString txt; if(! message->getFileTransferInformation() ){ foreach(auto content, message->getContents()){ if(content->isText()) txt += content->getStringBuffer().c_str(); } }else txt = tr("newFileMessage"); map["message"] = txt; shared_ptr chatRoom(message->getChatRoom()); map["peerAddress"] = Utils::coreStringToAppString(chatRoom->getPeerAddress()->asStringUriOnly()); map["localAddress"] = Utils::coreStringToAppString(chatRoom->getLocalAddress()->asStringUriOnly()); map["fullPeerAddress"] = Utils::coreStringToAppString(chatRoom->getPeerAddress()->asString()); map["fullLocalAddress"] = Utils::coreStringToAppString(chatRoom->getLocalAddress()->asString()); map["window"].setValue(App::getInstance()->getMainWindow()); CREATE_NOTIFICATION(Notifier::ReceivedMessage, map) } void Notifier::notifyReceivedFileMessage (const shared_ptr &message) { QVariantMap map; map["fileUri"] = Utils::coreStringToAppString(message->getFileTransferInformation()->getFilePath()); if( Utils::getImage(map["fileUri"].toString()).isNull()) map["imageUri"] = ""; else map["imageUri"] = map["fileUri"]; map["fileSize"] = quint64(message->getFileTransferInformation()->getSize() +message->getFileTransferInformation()->getFileSize()); CREATE_NOTIFICATION(Notifier::ReceivedFileMessage, map) } void Notifier::notifyReceivedCall (const shared_ptr &call) { CallModel *callModel = &call->getData("call-model"); QVariantMap map; map["call"].setValue(callModel); CREATE_NOTIFICATION(Notifier::ReceivedCall, map) QObject::connect(callModel, &CallModel::statusChanged, notification, [this, notification](CallModel::CallStatus status) { if (status == CallModel::CallStatusEnded || status == CallModel::CallStatusConnected) deleteNotification(QVariant::fromValue(notification)); }); } void Notifier::notifyNewVersionAvailable (const QString &version, const QString &url) { QVariantMap map; map["message"] = tr("newVersionAvailable").arg(version); map["url"] = url; CREATE_NOTIFICATION(Notifier::NewVersionAvailable, map) } void Notifier::notifySnapshotWasTaken (const QString &filePath) { QVariantMap map; map["filePath"] = filePath; CREATE_NOTIFICATION(Notifier::SnapshotWasTaken, map) } void Notifier::notifyRecordingCompleted (const QString &filePath) { QVariantMap map; map["filePath"] = filePath; CREATE_NOTIFICATION(Notifier::RecordingCompleted, map) } #undef SHOW_NOTIFICATION #undef CREATE_NOTIFICATION linphone-desktop-4.2.5/linphone-app/src/components/notifier/Notifier.hpp000066400000000000000000000046121376717241300265000ustar00rootroot00000000000000/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef NOTIFIER_H_ #define NOTIFIER_H_ #include #include #include // ============================================================================= class QMutex; class QQmlComponent; namespace linphone { class Call; class ChatMessage; } class Notifier : public QObject { Q_OBJECT; public: Notifier (QObject *parent = Q_NULLPTR); ~Notifier (); enum NotificationType { ReceivedMessage, ReceivedFileMessage, ReceivedCall, NewVersionAvailable, SnapshotWasTaken, RecordingCompleted }; void notifyReceivedMessage (const std::shared_ptr &message); void notifyReceivedFileMessage (const std::shared_ptr &message); void notifyReceivedCall (const std::shared_ptr &call); void notifyNewVersionAvailable (const QString &version, const QString &url); void notifySnapshotWasTaken (const QString &filePath); void notifyRecordingCompleted (const QString &filePath); public slots: void deleteNotification (QVariant notification); private: struct Notification { Notification (const QString &filename = QString(""), int timeout = 0) { this->filename = filename; this->timeout = timeout; } QString filename; int timeout; }; QObject *createNotification (NotificationType type, QVariantMap data); void showNotification (QObject *notification, int timeout); QHash mScreenHeightOffset; int mInstancesNumber = 0; QMutex *mMutex = nullptr; QQmlComponent **mComponents = nullptr; static const QHash Notifications; }; #endif // NOTIFIER_H_ linphone-desktop-4.2.5/linphone-app/src/components/other/000077500000000000000000000000001376717241300235075ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/src/components/other/clipboard/000077500000000000000000000000001376717241300254465ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/src/components/other/clipboard/Clipboard.cpp000066400000000000000000000025061376717241300300540ustar00rootroot00000000000000/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include #include #include "Clipboard.hpp" // ============================================================================= Clipboard::Clipboard (QObject *parent) : QObject(parent) { QObject::connect(QGuiApplication::clipboard(), &QClipboard::dataChanged, this, &Clipboard::textChanged); } QString Clipboard::getText () const { return QGuiApplication::clipboard()->text(QClipboard::Clipboard); } void Clipboard::setText (const QString &text) { QGuiApplication::clipboard()->setText(text, QClipboard::Clipboard); } linphone-desktop-4.2.5/linphone-app/src/components/other/clipboard/Clipboard.hpp000066400000000000000000000023511376717241300300570ustar00rootroot00000000000000/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef CLIPBOARD_H_ #define CLIPBOARD_H_ #include // ============================================================================= class Clipboard : public QObject { Q_OBJECT; Q_PROPERTY(QString text READ getText WRITE setText NOTIFY textChanged); public: Clipboard (QObject *parent = Q_NULLPTR); signals: void textChanged (); private: QString getText () const; void setText (const QString &text); }; #endif // ifndef CLIPBOARD_H_ linphone-desktop-4.2.5/linphone-app/src/components/other/colors/000077500000000000000000000000001376717241300250105ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/src/components/other/colors/Colors.cpp000066400000000000000000000054111376717241300267560ustar00rootroot00000000000000/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include #include #if LINPHONE_FRIDAY #include #endif // if LINPHONE_FRIDAY #include "utils/Utils.hpp" #include "Colors.hpp" // ============================================================================= using namespace std; namespace { constexpr char ColorsSection[] = "ui_colors"; } #if LINPHONE_FRIDAY static inline bool isLinphoneFriday () { return QDate::currentDate().dayOfWeek() == 5; } #endif // if LINPHONE_FRIDAY Colors::Colors (QObject *parent) : QObject(parent) { #if LINPHONE_FRIDAY if (isLinphoneFriday()) { setProperty("i", QColor("#F48D8D")); setProperty("b", QColor("#F58585")); setProperty("m", QColor("#FFC5C5")); } #endif // if LINPHONE_FRIDAY } void Colors::useConfig (const shared_ptr &config) { #if LINPHONE_FRIDAY if (!isLinphoneFriday()) overrideColors(config); #else overrideColors(config); #endif // if LINPHONE_FRIDAY } // ----------------------------------------------------------------------------- void Colors::overrideColors (const shared_ptr &config) { if (!config) return; const QMetaObject *info = metaObject(); for (int i = info->propertyOffset(); i < info->propertyCount(); ++i) { const QMetaProperty metaProperty = info->property(i); const string colorName = metaProperty.name(); const string colorValue = config->getString(ColorsSection, colorName, ""); if (!colorValue.empty()) setProperty(colorName.c_str(), QColor(Utils::coreStringToAppString(colorValue))); } } QStringList Colors::getColorNames () const { static QStringList colorNames; if (!colorNames.isEmpty()) return colorNames; const QMetaObject *info = metaObject(); for (int i = info->propertyOffset(); i < info->propertyCount(); ++i) { const QMetaProperty metaProperty = info->property(i); if (metaProperty.isWritable()) colorNames << QString::fromLatin1(metaProperty.name()); } return colorNames; } linphone-desktop-4.2.5/linphone-app/src/components/other/colors/Colors.hpp000066400000000000000000000075731376717241300267760ustar00rootroot00000000000000/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef COLORS_H_ #define COLORS_H_ #include #include #include // ============================================================================= #define ADD_COLOR(COLOR, VALUE) \ Q_PROPERTY(QColor COLOR MEMBER m ## COLOR WRITE set ## COLOR NOTIFY colorT ## COLOR ## Changed); \ void set ## COLOR(const QColor &color) { \ m ## COLOR = color; \ emit colorT ## COLOR ## Changed(m ## COLOR); \ } \ QColor m ## COLOR = VALUE; // Alpha is in percent. #define ADD_COLOR_WITH_ALPHA(COLOR, ALPHA) \ Q_PROPERTY(QColor COLOR ## ALPHA READ get ## COLOR ## ALPHA NOTIFY colorT ## COLOR ## Changed); \ QColor get ## COLOR ## ALPHA() { \ QColor color = m ## COLOR; \ color.setAlpha(ALPHA * 255 / 100); \ return color; \ } // ----------------------------------------------------------------------------- namespace linphone { class Config; } class Colors : public QObject { Q_OBJECT Q_PROPERTY(QStringList colorNames READ getColorNames CONSTANT) ADD_COLOR(a, "transparent") // Primary color for hovered items. ADD_COLOR(b, "#D64D00") ADD_COLOR(c, "#CBCBCB") ADD_COLOR(d, "#5A585B") ADD_COLOR(e, "#F3F3F3") ADD_COLOR(f, "#E8E8E8") ADD_COLOR(g, "#6B7A86") ADD_COLOR(h, "#687680") // Primary color. ADD_COLOR(i, "#FE5E00") ADD_COLOR(j, "#4B5964") // Popups, home, call, assistant and settings background. ADD_COLOR(k, "#FFFFFF") ADD_COLOR(l, "#000000") // Primary color for clicked items. ADD_COLOR(m, "#FF8600") ADD_COLOR(n, "#A1A1A1") ADD_COLOR(o, "#D0D8DE") // Progress bar. ADD_COLOR(p, "#17A81A") // Fields, backgrounds and text color on some items. ADD_COLOR(q, "#FFFFFF") // Field error. ADD_COLOR(error, "#FF0000") ADD_COLOR_WITH_ALPHA(g, 10) ADD_COLOR_WITH_ALPHA(g, 20) ADD_COLOR_WITH_ALPHA(g, 90) ADD_COLOR_WITH_ALPHA(i, 30) ADD_COLOR_WITH_ALPHA(l, 50) ADD_COLOR_WITH_ALPHA(l, 80) ADD_COLOR_WITH_ALPHA(q, 50) public: Colors (QObject *parent = Q_NULLPTR); void useConfig (const std::shared_ptr &config); signals: void colorTaChanged (const QColor &color); void colorTbChanged (const QColor &color); void colorTcChanged (const QColor &color); void colorTdChanged (const QColor &color); void colorTeChanged (const QColor &color); void colorTfChanged (const QColor &color); void colorTgChanged (const QColor &color); void colorThChanged (const QColor &color); void colorTiChanged (const QColor &color); void colorTjChanged (const QColor &color); void colorTkChanged (const QColor &color); void colorTlChanged (const QColor &color); void colorTmChanged (const QColor &color); void colorTnChanged (const QColor &color); void colorToChanged (const QColor &color); void colorTpChanged (const QColor &color); void colorTqChanged (const QColor &color); void colorTerrorChanged (const QColor &color); private: void overrideColors (const std::shared_ptr &config); QStringList getColorNames () const; }; // ----------------------------------------------------------------------------- #undef ADD_COLOR_WITH_ALPHA #undef ADD_COLOR #endif // COLORS_H_ linphone-desktop-4.2.5/linphone-app/src/components/other/desktop-tools/000077500000000000000000000000001376717241300263165ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/src/components/other/desktop-tools/DesktopTools.hpp000066400000000000000000000022061376717241300314610ustar00rootroot00000000000000/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef DESKTOP_TOOLS_H_ #define DESKTOP_TOOLS_H_ #include #ifdef Q_OS_LINUX #include "DesktopToolsLinux.hpp" #elif defined(Q_OS_WIN) #include "DesktopToolsWindows.hpp" #else #include "DesktopToolsMacOs.hpp" #endif // ifdef Q_OS_LINUX // ============================================================================= #endif // DESKTOP_TOOLS_H_ linphone-desktop-4.2.5/linphone-app/src/components/other/desktop-tools/DesktopToolsLinux.cpp000066400000000000000000000026511376717241300325000ustar00rootroot00000000000000/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "DesktopToolsLinux.hpp" // ============================================================================= DesktopTools::~DesktopTools () { setScreenSaverStatus(true); } bool DesktopTools::getScreenSaverStatus () const { return mScreenSaverStatus; } void DesktopTools::setScreenSaverStatus (bool status) { screenSaverDBus.setScreenSaverStatus(status); screenSaverXdg.setScreenSaverStatus(status); bool newStatus = screenSaverDBus.getScreenSaverStatus() || screenSaverXdg.getScreenSaverStatus(); if (newStatus != mScreenSaverStatus) { mScreenSaverStatus = newStatus; emit screenSaverStatusChanged(mScreenSaverStatus); } } linphone-desktop-4.2.5/linphone-app/src/components/other/desktop-tools/DesktopToolsLinux.hpp000066400000000000000000000033061376717241300325030ustar00rootroot00000000000000/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef DESKTOP_TOOLS_LINUX_H_ #define DESKTOP_TOOLS_LINUX_H_ #include "components/other/desktop-tools/screen-saver/ScreenSaverDBus.hpp" #include "components/other/desktop-tools/screen-saver/ScreenSaverXdg.hpp" // ============================================================================= class DesktopTools : public QObject { Q_OBJECT; Q_PROPERTY(bool screenSaverStatus READ getScreenSaverStatus WRITE setScreenSaverStatus NOTIFY screenSaverStatusChanged); public: DesktopTools (QObject *parent = Q_NULLPTR) : QObject(parent) {} ~DesktopTools (); bool getScreenSaverStatus () const; void setScreenSaverStatus (bool status); static void init(){} static void applicationStateChanged(Qt::ApplicationState){}; signals: void screenSaverStatusChanged (bool status); private: bool mScreenSaverStatus = true; ScreenSaverDBus screenSaverDBus; ScreenSaverXdg screenSaverXdg; }; #endif // DESKTOP_TOOLS_LINUX_H_ linphone-desktop-4.2.5/linphone-app/src/components/other/desktop-tools/DesktopToolsMacOs.cpp000066400000000000000000000026751376717241300324110ustar00rootroot00000000000000/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "DesktopToolsMacOs.hpp" // ============================================================================= extern "C" bool enableScreenSaverMacOs (); extern "C" bool disableScreenSaverMacOs (); DesktopTools::DesktopTools (QObject *parent) : QObject(parent) {} DesktopTools::~DesktopTools () { setScreenSaverStatus(true); } bool DesktopTools::getScreenSaverStatus () const { return mScreenSaverStatus; } void DesktopTools::setScreenSaverStatus (bool status) { if (status != mScreenSaverStatus && (status ? enableScreenSaverMacOs() : disableScreenSaverMacOs())) { mScreenSaverStatus = status; emit screenSaverStatusChanged(mScreenSaverStatus); } } linphone-desktop-4.2.5/linphone-app/src/components/other/desktop-tools/DesktopToolsMacOs.hpp000066400000000000000000000030231376717241300324020ustar00rootroot00000000000000/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef DESKTOP_TOOLS_MAC_OS_H_ #define DESKTOP_TOOLS_MAC_OS_H_ #include // ============================================================================= class DesktopTools : public QObject { Q_OBJECT; Q_PROPERTY(bool screenSaverStatus READ getScreenSaverStatus WRITE setScreenSaverStatus NOTIFY screenSaverStatusChanged); public: DesktopTools (QObject *parent = Q_NULLPTR); ~DesktopTools (); bool getScreenSaverStatus () const; void setScreenSaverStatus (bool status); static void init(); // Do first initialization static void applicationStateChanged(Qt::ApplicationState currentState); signals: void screenSaverStatusChanged (bool status); private: bool mScreenSaverStatus = true; }; #endif // DESKTOP_TOOLS_MAC_OS_H_ linphone-desktop-4.2.5/linphone-app/src/components/other/desktop-tools/DesktopToolsMacOs.mm000066400000000000000000000010751376717241300322310ustar00rootroot00000000000000#include "DesktopToolsMacOs.hpp" #import void DesktopTools::init(){ // Request permissions if( @available(macOS 10.14, *) ) { if([AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo] == AVAuthorizationStatusNotDetermined) [AVCaptureDevice requestAccessForMediaType:AVMediaTypeVideo completionHandler:^(BOOL) {}]; if([AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeAudio] == AVAuthorizationStatusNotDetermined) [AVCaptureDevice requestAccessForMediaType:AVMediaTypeAudio completionHandler:^(BOOL) {}]; } } linphone-desktop-4.2.5/linphone-app/src/components/other/desktop-tools/DesktopToolsWindows.cpp000066400000000000000000000026661376717241300330410ustar00rootroot00000000000000/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "DesktopToolsWindows.hpp" #include // ============================================================================= DesktopTools::DesktopTools (QObject *parent) : QObject(parent) {} DesktopTools::~DesktopTools () { setScreenSaverStatus(true); } bool DesktopTools::getScreenSaverStatus () const { return mScreenSaverStatus; } void DesktopTools::setScreenSaverStatus (bool status) { if (status == mScreenSaverStatus) return; if (status) SetThreadExecutionState(ES_CONTINUOUS); else SetThreadExecutionState(ES_CONTINUOUS | ES_DISPLAY_REQUIRED); mScreenSaverStatus = status; emit screenSaverStatusChanged(status); } linphone-desktop-4.2.5/linphone-app/src/components/other/desktop-tools/DesktopToolsWindows.hpp000066400000000000000000000027611376717241300330420ustar00rootroot00000000000000/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef DESKTOP_TOOLS_WINDOWS_H_ #define DESKTOP_TOOLS_WINDOWS_H_ #include // ============================================================================= class DesktopTools : public QObject { Q_OBJECT; Q_PROPERTY(bool screenSaverStatus READ getScreenSaverStatus WRITE setScreenSaverStatus NOTIFY screenSaverStatusChanged); public: DesktopTools (QObject *parent = Q_NULLPTR); ~DesktopTools (); bool getScreenSaverStatus () const; void setScreenSaverStatus (bool status); static void init(){} static void applicationStateChanged(Qt::ApplicationState){}; signals: void screenSaverStatusChanged (bool status); private: bool mScreenSaverStatus = true; }; #endif // DESKTOP_TOOLS_WINDOWS_H_ linphone-desktop-4.2.5/linphone-app/src/components/other/desktop-tools/screen-saver/000077500000000000000000000000001376717241300307135ustar00rootroot00000000000000ScreenSaverDBus.cpp000066400000000000000000000050061376717241300343370ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/src/components/other/desktop-tools/screen-saver/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include #include #include #include #include "ScreenSaverDBus.hpp" // ============================================================================= namespace { constexpr char ServiceName[] = "org.freedesktop.ScreenSaver"; constexpr char ServicePath[] = "/ScreenSaver"; } ScreenSaverDBus::ScreenSaverDBus (QObject *parent) : QObject(parent), mBus(ServiceName, ServicePath, ServiceName) {} ScreenSaverDBus::~ScreenSaverDBus () { setScreenSaverStatus(true); } bool ScreenSaverDBus::getScreenSaverStatus () const { return mScreenSaverStatus; } void ScreenSaverDBus::setScreenSaverStatus (bool status) { if (status == mScreenSaverStatus) return; if (status) { QDBusMessage reply(mBus.call("UnInhibit", mToken)); if (reply.type() == QDBusMessage::ErrorMessage) { qWarning() << QStringLiteral("Uninhibit screen saver failed: `%1: %2`.") .arg(reply.errorName()).arg(reply.errorMessage()); return; } else qInfo("Uninhibit screen saver."); mToken = uint32_t(reply.arguments().first().toULongLong()); mScreenSaverStatus = status; emit screenSaverStatusChanged(mScreenSaverStatus); return; } QDBusMessage reply(mBus.call("Inhibit", QCoreApplication::applicationName(), "Inhibit asked for video stream")); if (reply.type() == QDBusMessage::ErrorMessage) { if (reply.errorName() != QLatin1String("org.freedesktop.DBus.Error.ServiceUnknown")) qWarning() << QStringLiteral("Inhibit screen saver failed: `%1: %2`.") .arg(reply.errorName()).arg(reply.errorMessage()); return; } else qInfo("Inhibit screen saver."); mScreenSaverStatus = status; emit screenSaverStatusChanged(mScreenSaverStatus); } ScreenSaverDBus.hpp000066400000000000000000000025551376717241300343520ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/src/components/other/desktop-tools/screen-saver/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef SCREEN_SAVER_DBUS_H_ #define SCREEN_SAVER_DBUS_H_ #include // ============================================================================= class QDBusPendingCallWatcher; class ScreenSaverDBus : public QObject { Q_OBJECT; public: ScreenSaverDBus (QObject *parent = Q_NULLPTR); ~ScreenSaverDBus (); bool getScreenSaverStatus () const; void setScreenSaverStatus (bool status); signals: void screenSaverStatusChanged (bool status); private: bool mScreenSaverStatus = true; QDBusInterface mBus; uint32_t mToken; }; #endif // SCREEN_SAVER_DBUS_H_ ScreenSaverMacOs.m000066400000000000000000000030561376717241300341610ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/src/components/other/desktop-tools/screen-saver/* * ScreenSaverMacOS.m * Copyright (C) 2017-2018 Belledonne Communications, Grenoble, France * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * Created on: August 3, 2018 * Author: Ronan Abhamon */ #import // ============================================================================= static bool ScreenSaverEnabled = true; static IOPMAssertionID AssertionID; bool enableScreenSaverMacOs () { if (ScreenSaverEnabled) return true; ScreenSaverEnabled = IOPMAssertionRelease(AssertionID) == kIOReturnSuccess; return ScreenSaverEnabled; } bool disableScreenSaverMacOs () { if (!ScreenSaverEnabled) return true; ScreenSaverEnabled = IOPMAssertionCreateWithName( kIOPMAssertionTypeNoDisplaySleep, kIOPMAssertionLevelOn, CFSTR("Inhibit asked for video stream"), &AssertionID ) != kIOReturnSuccess; return !ScreenSaverEnabled; } ScreenSaverXdg.cpp000066400000000000000000000031321376717241300342220ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/src/components/other/desktop-tools/screen-saver/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include #include "ScreenSaverXdg.hpp" // ============================================================================= namespace { constexpr char Program[] = "xdg-screensaver"; const QStringList Arguments{"reset"}; constexpr int Interval = 30000; } ScreenSaverXdg::ScreenSaverXdg (QObject *parent) : QObject(parent) { mTimer.setInterval(Interval); QObject::connect(&mTimer, &QTimer::timeout, []() { // Legacy for systems without DBus screensaver. QProcess::startDetached(Program, Arguments); }); } bool ScreenSaverXdg::getScreenSaverStatus () const { return !mTimer.isActive(); } void ScreenSaverXdg::setScreenSaverStatus (bool status) { if (status == !mTimer.isActive()) return; if (status) mTimer.stop(); else mTimer.start(); emit screenSaverStatusChanged(status); } ScreenSaverXdg.hpp000066400000000000000000000023551376717241300342350ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/src/components/other/desktop-tools/screen-saver/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef SCREEN_SAVER_XDG_H_ #define SCREEN_SAVER_XDG_H_ #include // ============================================================================= class ScreenSaverXdg : public QObject { Q_OBJECT; public: ScreenSaverXdg (QObject *parent = Q_NULLPTR); bool getScreenSaverStatus () const; void setScreenSaverStatus (bool status); signals: void screenSaverStatusChanged (bool status); private: QTimer mTimer; }; #endif // SCREEN_SAVER_XDG_H_ linphone-desktop-4.2.5/linphone-app/src/components/other/desktop-tools/state-process/000077500000000000000000000000001376717241300311125ustar00rootroot00000000000000StateProcessMacOs.mm000066400000000000000000000015501376717241300347310ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/src/components/other/desktop-tools/state-process#include "../DesktopToolsMacOs.hpp" #import #import // Store a unique global instance of Activity to avoid App Nap of MacOs static id g_backgroundActivity =0; void DesktopTools::applicationStateChanged(Qt::ApplicationState p_currentState) { if( p_currentState == Qt::ApplicationActive && g_backgroundActivity != 0 ) {// Entering Foreground [[NSProcessInfo processInfo] endActivity:g_backgroundActivity]; [g_backgroundActivity release]; g_backgroundActivity = 0; }else if( g_backgroundActivity == 0 ) {// Doesn't begin activity if it is already started g_backgroundActivity = [[NSProcessInfo processInfo] beginActivityWithOptions:NSActivityUserInitiatedAllowingIdleSystemSleep reason:@"Linphone : Continue to receive requests while in Background"]; [g_backgroundActivity retain]; } } linphone-desktop-4.2.5/linphone-app/src/components/other/text-to-speech/000077500000000000000000000000001376717241300263605ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/src/components/other/text-to-speech/TextToSpeech.cpp000066400000000000000000000027571376717241300314560ustar00rootroot00000000000000/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifdef TEXTTOSPEECH_ENABLED #include #endif // ifdef TEXTTOSPEECH_ENABLED #include "TextToSpeech.hpp" // ============================================================================= #ifdef TEXTTOSPEECH_ENABLED TextToSpeech::TextToSpeech (QObject *parent) : QObject(parent) { mQtTextToSpeech = new QTextToSpeech(this); } void TextToSpeech::say (const QString &text) { mQtTextToSpeech->say(text); } bool TextToSpeech::available () const { return true; } #else TextToSpeech::TextToSpeech (QObject *parent) : QObject(parent) {} void TextToSpeech::say (const QString &) {} bool TextToSpeech::available () const { return false; } #endif // ifdef TEXTTOSPEECH_ENABLED linphone-desktop-4.2.5/linphone-app/src/components/other/text-to-speech/TextToSpeech.hpp000066400000000000000000000024231376717241300314510ustar00rootroot00000000000000/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef TEXT_TO_SPEECH_H_ #define TEXT_TO_SPEECH_H_ #include // ============================================================================= class QTextToSpeech; class TextToSpeech : public QObject { Q_OBJECT; Q_PROPERTY(bool available READ available CONSTANT); public: TextToSpeech (QObject *parent = Q_NULLPTR); Q_INVOKABLE void say (const QString &text); private: bool available () const; QTextToSpeech *mQtTextToSpeech = nullptr; }; #endif // ifndef TEXT_TO_SPEECH_H_ linphone-desktop-4.2.5/linphone-app/src/components/other/units/000077500000000000000000000000001376717241300246515ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/src/components/other/units/Units.cpp000066400000000000000000000020661376717241300264630ustar00rootroot00000000000000/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "Units.hpp" // ============================================================================= Units::Units (QObject *parent) : QObject(parent) {} float Units::getDp () const { #ifdef Q_OS_MACOS return float(96.0 / 72.0); #endif // ifdef Q_OS_MACOS return 1.0; } linphone-desktop-4.2.5/linphone-app/src/components/other/units/Units.hpp000066400000000000000000000021441376717241300264650ustar00rootroot00000000000000/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef UNITS_H_ #define UNITS_H_ #include // ============================================================================= class Units : public QObject { Q_OBJECT; Q_PROPERTY(float dp READ getDp CONSTANT); public: Units (QObject *parent = Q_NULLPTR); private: float getDp () const; }; #endif // UNITS_H_ linphone-desktop-4.2.5/linphone-app/src/components/presence/000077500000000000000000000000001376717241300241725ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/src/components/presence/OwnPresenceModel.cpp000066400000000000000000000060341376717241300301120ustar00rootroot00000000000000/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include #include "components/core/CoreManager.hpp" #include "components/settings/AccountSettingsModel.hpp" #include "OwnPresenceModel.hpp" // ============================================================================= using namespace std; OwnPresenceModel::OwnPresenceModel (QObject *parent) : QObject(parent) { AccountSettingsModel *accountSettingsModel = CoreManager::getInstance()->getAccountSettingsModel(); // Update status when changing the publish presence from settings QObject::connect(accountSettingsModel, &AccountSettingsModel::publishPresenceChanged, this, [this]() { Presence::PresenceStatus status = static_cast(CoreManager::getInstance()->getCore()->getConsolidatedPresence()); emit presenceStatusChanged(status); emit presenceLevelChanged(Presence::getPresenceLevel(status)); }); } Presence::PresenceLevel OwnPresenceModel::getPresenceLevel () const { return Presence::getPresenceLevel(getPresenceStatus()); } Presence::PresenceStatus OwnPresenceModel::getPresenceStatus () const { return static_cast(CoreManager::getInstance()->getCore()->getConsolidatedPresence()); } void OwnPresenceModel::setPresenceStatus (Presence::PresenceStatus status) { shared_ptr core = CoreManager::getInstance()->getCore(); core->setConsolidatedPresence(static_cast(status)); emit presenceStatusChanged(status); emit presenceLevelChanged(Presence::getPresenceLevel(status)); } // ----------------------------------------------------------------------------- static inline void addBuildStatus (QVariantList &list, Presence::PresenceStatus status) { Presence::PresenceLevel level = Presence::getPresenceLevel(status); QVariantMap map; map["presenceLevel"] = level; map["presenceStatus"] = status; map["presenceIcon"] = Presence::getPresenceLevelIconName(level); map["presenceLabel"] = Presence::getPresenceStatusAsString(status); list << map; } QVariantList OwnPresenceModel::getStatuses () const { QVariantList statuses; addBuildStatus(statuses, Presence::Online); addBuildStatus(statuses, Presence::Busy); addBuildStatus(statuses, Presence::DoNotDisturb); addBuildStatus(statuses, Presence::Offline); return statuses; } linphone-desktop-4.2.5/linphone-app/src/components/presence/OwnPresenceModel.hpp000066400000000000000000000036661376717241300301270ustar00rootroot00000000000000/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef OWN_PRESENCE_MODEL_H_ #define OWN_PRESENCE_MODEL_H_ #include "Presence.hpp" // ============================================================================= // Gives the statuses list informations (icons, label, level, status). // Can set/get the presence status of the linphone user app. // ============================================================================= class OwnPresenceModel : public QObject { Q_OBJECT; Q_PROPERTY(QVariantList statuses READ getStatuses CONSTANT); Q_PROPERTY(Presence::PresenceLevel presenceLevel READ getPresenceLevel NOTIFY presenceLevelChanged); Q_PROPERTY(Presence::PresenceStatus presenceStatus READ getPresenceStatus WRITE setPresenceStatus NOTIFY presenceStatusChanged); public: OwnPresenceModel (QObject *parent = Q_NULLPTR); signals: void presenceLevelChanged (Presence::PresenceLevel level); void presenceStatusChanged (Presence::PresenceStatus status); private: Presence::PresenceLevel getPresenceLevel () const; Presence::PresenceStatus getPresenceStatus () const; void setPresenceStatus (Presence::PresenceStatus status); QVariantList getStatuses () const; }; #endif // OWN_PRESENCE_MODEL_H_ linphone-desktop-4.2.5/linphone-app/src/components/presence/Presence.cpp000066400000000000000000000034701376717241300264460ustar00rootroot00000000000000/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "Presence.hpp" // ============================================================================= Presence::PresenceLevel Presence::getPresenceLevel (const PresenceStatus &status) { switch (status) { case Online: return Green; case Busy: return Orange; case DoNotDisturb: return Red; default: break; } return White; } QString Presence::getPresenceStatusAsString (const PresenceStatus &status) { switch (status) { case Online: return tr("presenceOnline"); case Busy: return tr("presenceBusy"); case DoNotDisturb: return tr("presenceDoNotDisturb"); default: break; } return tr("presenceOffline"); } QString Presence::getPresenceLevelIconName (const PresenceLevel &level) { switch (level) { case Green: return QStringLiteral("led_green"); case Orange: return QStringLiteral("led_orange"); case Red: return QStringLiteral("led_red"); case White: return QStringLiteral("led_white"); } return QString(""); } linphone-desktop-4.2.5/linphone-app/src/components/presence/Presence.hpp000066400000000000000000000036331376717241300264540ustar00rootroot00000000000000/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef PRESENCE_H_ #define PRESENCE_H_ #include #include // ============================================================================= // A helper to get the presence level of a presence status and to get a // presence status as string. // ============================================================================= class Presence : public QObject { Q_OBJECT; public: enum PresenceStatus { Online = int(linphone::ConsolidatedPresence::Online), Busy = int(linphone::ConsolidatedPresence::Busy), DoNotDisturb = int(linphone::ConsolidatedPresence::DoNotDisturb), Offline = int(linphone::ConsolidatedPresence::Offline) }; Q_ENUM(PresenceStatus); enum PresenceLevel { Green, Orange, Red, White }; Q_ENUM(PresenceLevel); Presence (QObject *parent = Q_NULLPTR) : QObject(parent) {} Q_INVOKABLE static PresenceLevel getPresenceLevel (const PresenceStatus &status); Q_INVOKABLE static QString getPresenceStatusAsString (const PresenceStatus &status); Q_INVOKABLE static QString getPresenceLevelIconName (const PresenceLevel &level); }; #endif // PRESENCE_H_ linphone-desktop-4.2.5/linphone-app/src/components/settings/000077500000000000000000000000001376717241300242265ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/src/components/settings/AccountSettingsModel.cpp000066400000000000000000000410171376717241300310330ustar00rootroot00000000000000/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include #include "config.h" #include "app/paths/Paths.hpp" #include "components/core/CoreHandlers.hpp" #include "components/core/CoreManager.hpp" #include "utils/Utils.hpp" #include "AccountSettingsModel.hpp" #include "SettingsModel.hpp" // ============================================================================= using namespace std; static inline AccountSettingsModel::RegistrationState mapLinphoneRegistrationStateToUi (linphone::RegistrationState state) { switch (state) { case linphone::RegistrationState::None: case linphone::RegistrationState::Cleared: case linphone::RegistrationState::Failed: return AccountSettingsModel::RegistrationStateNotRegistered; case linphone::RegistrationState::Progress: return AccountSettingsModel::RegistrationStateInProgress; case linphone::RegistrationState::Ok: break; } return AccountSettingsModel::RegistrationStateRegistered; } // ----------------------------------------------------------------------------- AccountSettingsModel::AccountSettingsModel (QObject *parent) : QObject(parent) { CoreManager *coreManager = CoreManager::getInstance(); QObject::connect( coreManager->getHandlers().get(), &CoreHandlers::registrationStateChanged, this, &AccountSettingsModel::handleRegistrationStateChanged ); QObject::connect(coreManager, &CoreManager::eventCountChanged, this, [this]() { emit accountSettingsUpdated(); }); } // ----------------------------------------------------------------------------- shared_ptr AccountSettingsModel::getUsedSipAddress () const { shared_ptr core = CoreManager::getInstance()->getCore(); shared_ptr proxyConfig = core->getDefaultProxyConfig(); return proxyConfig?proxyConfig->getIdentityAddress():core->createPrimaryContactParsed(); } void AccountSettingsModel::setUsedSipAddress (const shared_ptr &address) { shared_ptr core = CoreManager::getInstance()->getCore(); shared_ptr proxyConfig = core->getDefaultProxyConfig(); proxyConfig ? proxyConfig->setIdentityAddress(address) : core->setPrimaryContact(address->asString()); } QString AccountSettingsModel::getUsedSipAddressAsStringUriOnly () const { return Utils::coreStringToAppString(getUsedSipAddress()->asStringUriOnly()); } QString AccountSettingsModel::getUsedSipAddressAsString () const { return Utils::coreStringToAppString(getUsedSipAddress()->asString()); } // ----------------------------------------------------------------------------- bool AccountSettingsModel::addOrUpdateProxyConfig (const shared_ptr &proxyConfig) { Q_CHECK_PTR(proxyConfig); CoreManager *coreManager = CoreManager::getInstance(); shared_ptr core = coreManager->getCore(); list> proxyConfigs = core->getProxyConfigList(); if (find(proxyConfigs.cbegin(), proxyConfigs.cend(), proxyConfig) != proxyConfigs.cend()) { if (proxyConfig->done() == -1) { qWarning() << QStringLiteral("Unable to update proxy config: `%1`.") .arg(Utils::coreStringToAppString(proxyConfig->getIdentityAddress()->asString())); return false; } coreManager->getSettingsModel()->configureRlsUri(); } else { if (core->addProxyConfig(proxyConfig) == -1) { qWarning() << QStringLiteral("Unable to add proxy config: `%1`.") .arg(Utils::coreStringToAppString(proxyConfig->getIdentityAddress()->asString())); return false; } coreManager->getSettingsModel()->configureRlsUri(proxyConfig); } emit accountSettingsUpdated(); return true; } QVariantMap AccountSettingsModel::getProxyConfigDescription (const shared_ptr &proxyConfig) { Q_CHECK_PTR(proxyConfig); QVariantMap map; { const shared_ptr address = proxyConfig->getIdentityAddress(); map["sipAddress"] = address ? Utils::coreStringToAppString(proxyConfig->getIdentityAddress()->asString()) : QString(""); } map["serverAddress"] = Utils::coreStringToAppString(proxyConfig->getServerAddr()); map["registrationDuration"] = proxyConfig->getPublishExpires(); if( map["serverAddress"].toString().toUpper().contains("TRANSPORT="))// transport has been specified : let the RFC select the transport map["transport"] = Utils::coreStringToAppString(proxyConfig->getTransport()); else// Set to TLS as default map["transport"] = "tls"; if( proxyConfig->getRoutes().size() > 0) map["route"] = Utils::coreStringToAppString(proxyConfig->getRoutes().front()); else map["route"] = ""; map["contactParams"] = Utils::coreStringToAppString(proxyConfig->getContactParameters()); map["avpfInterval"] = proxyConfig->getAvpfRrInterval(); map["registerEnabled"] = proxyConfig->registerEnabled(); map["publishPresence"] = proxyConfig->publishEnabled(); map["avpfEnabled"] = proxyConfig->getAvpfMode() == linphone::AVPFMode::Enabled; map["registrationState"] = mapLinphoneRegistrationStateToUi(proxyConfig->getState()); shared_ptr natPolicy = proxyConfig->getNatPolicy(); bool createdNat = !natPolicy; if (createdNat) natPolicy = proxyConfig->getCore()->createNatPolicy(); map["iceEnabled"] = natPolicy->iceEnabled(); map["turnEnabled"] = natPolicy->turnEnabled(); const string &turnUser(natPolicy->getStunServerUsername()); const string &stunServer(natPolicy->getStunServer()); map["turnUser"] = Utils::coreStringToAppString(turnUser); map["stunServer"] = Utils::coreStringToAppString(stunServer); if (createdNat) proxyConfig->setNatPolicy(natPolicy); shared_ptr authInfo = CoreManager::getInstance()->getCore()->findAuthInfo( "", turnUser, stunServer ); map["turnPassword"] = authInfo ? Utils::coreStringToAppString(authInfo->getPassword()) : QString(""); return map; } void AccountSettingsModel::setDefaultProxyConfig (const shared_ptr &proxyConfig) { shared_ptr core = CoreManager::getInstance()->getCore(); if (core->getDefaultProxyConfig() != proxyConfig) { core->setDefaultProxyConfig(proxyConfig); emit accountSettingsUpdated(); } } void AccountSettingsModel::setDefaultProxyConfigFromSipAddress (const QString &sipAddress) { shared_ptr core = CoreManager::getInstance()->getCore(); if (Utils::coreStringToAppString(core->createPrimaryContactParsed()->asStringUriOnly()) == sipAddress) { setDefaultProxyConfig(nullptr); return; } for (const auto &proxyConfig : core->getProxyConfigList()) if (Utils::coreStringToAppString(proxyConfig->getIdentityAddress()->asStringUriOnly()) == sipAddress) { setDefaultProxyConfig(proxyConfig); return; } qWarning() << "Unable to set default proxy config from:" << sipAddress; } void AccountSettingsModel::removeProxyConfig (const shared_ptr &proxyConfig) { Q_CHECK_PTR(proxyConfig); CoreManager *coreManager = CoreManager::getInstance(); std::list> allProxies = coreManager->getCore()->getProxyConfigList(); std::shared_ptr proxyAddress = proxyConfig->getIdentityAddress(); coreManager->getCore()->removeProxyConfig(proxyConfig);// Remove first to avoid requesting password when deleting it if(proxyConfig->findAuthInfo()) coreManager->getCore()->removeAuthInfo(proxyConfig->findAuthInfo());// Remove passwords coreManager->getSettingsModel()->configureRlsUri(); emit accountSettingsUpdated(); } bool AccountSettingsModel::addOrUpdateProxyConfig ( const shared_ptr &proxyConfig, const QVariantMap &data ) { Q_CHECK_PTR(proxyConfig); bool newPublishPresence = false; proxyConfig->edit(); QString literal = data["sipAddress"].toString(); // Sip address. { shared_ptr address = linphone::Factory::get()->createAddress( Utils::appStringToCoreString(literal) ); if (!address) { qWarning() << QStringLiteral("Unable to create sip address object from: `%1`.").arg(literal); return false; } if (proxyConfig->setIdentityAddress(address)) { qWarning() << QStringLiteral("Unable to set identity address: `%1`.") .arg(Utils::coreStringToAppString(address->asStringUriOnly())); return false; } } // Server address. { QString serverAddress = data["serverAddress"].toString(); if (proxyConfig->setServerAddr(Utils::appStringToCoreString(serverAddress))) { qWarning() << QStringLiteral("Unable to add server address: `%1`.").arg(serverAddress); return false; } } proxyConfig->setPublishExpires(data["registrationDuration"].toInt()); proxyConfig->setRoute(Utils::appStringToCoreString(data["route"].toString())); proxyConfig->setContactParameters(Utils::appStringToCoreString(data["contactParams"].toString())); proxyConfig->setAvpfRrInterval(uint8_t(data["avpfInterval"].toInt())); proxyConfig->enableRegister(data["registerEnabled"].toBool()); newPublishPresence = proxyConfig->publishEnabled() != data["publishPresence"].toBool(); proxyConfig->enablePublish(data["publishPresence"].toBool()); proxyConfig->setAvpfMode(data["avpfEnabled"].toBool() ? linphone::AVPFMode::Enabled : linphone::AVPFMode::Default ); shared_ptr natPolicy = proxyConfig->getNatPolicy(); bool createdNat = !natPolicy; if (createdNat) natPolicy = proxyConfig->getCore()->createNatPolicy(); natPolicy->enableIce(data["iceEnabled"].toBool()); natPolicy->enableStun(data["iceEnabled"].toBool()); const string turnUser(Utils::appStringToCoreString(data["turnUser"].toString())); const string stunServer(Utils::appStringToCoreString(data["stunServer"].toString())); natPolicy->enableTurn(data["turnEnabled"].toBool()); natPolicy->setStunServerUsername(turnUser); natPolicy->setStunServer(stunServer); if( createdNat) proxyConfig->setNatPolicy(natPolicy); shared_ptr core(proxyConfig->getCore()); shared_ptr authInfo(core->findAuthInfo("", turnUser, stunServer)); if (authInfo) { shared_ptr clonedAuthInfo(authInfo->clone()); clonedAuthInfo->setUserid(turnUser); clonedAuthInfo->setUsername(turnUser); clonedAuthInfo->setPassword(Utils::appStringToCoreString(data["turnPassword"].toString())); core->addAuthInfo(clonedAuthInfo); core->removeAuthInfo(authInfo); } else core->addAuthInfo(linphone::Factory::get()->createAuthInfo( turnUser, turnUser, Utils::appStringToCoreString(data["turnPassword"].toString()), "", stunServer, "" )); if( newPublishPresence) emit publishPresenceChanged(); return addOrUpdateProxyConfig(proxyConfig); } shared_ptr AccountSettingsModel::createProxyConfig () { shared_ptr core = CoreManager::getInstance()->getCore(); core->getConfig()->loadFromXmlFile( Paths::getAssistantConfigDirPath() + "create-app-sip-account.rc" ); return core->createProxyConfig(); } void AccountSettingsModel::addAuthInfo ( const shared_ptr &authInfo, const QString &password, const QString &userId ) { authInfo->setPassword(Utils::appStringToCoreString(password)); authInfo->setUserid(Utils::appStringToCoreString(userId)); CoreManager::getInstance()->getCore()->addAuthInfo(authInfo); } void AccountSettingsModel::eraseAllPasswords () { CoreManager::getInstance()->getCore()->clearAllAuthInfo(); } // ----------------------------------------------------------------------------- QString AccountSettingsModel::getUsername () const { shared_ptr address = getUsedSipAddress(); const string displayName = address->getDisplayName(); return Utils::coreStringToAppString( displayName.empty() ? address->getUsername() : displayName ); } void AccountSettingsModel::setUsername (const QString &username) { shared_ptr address = getUsedSipAddress(); shared_ptr newAddress = address->clone(); if (newAddress->setDisplayName(Utils::appStringToCoreString(username))) { qWarning() << QStringLiteral("Unable to set displayName on sip address: `%1`.") .arg(Utils::coreStringToAppString(newAddress->asStringUriOnly())); } else { setUsedSipAddress(newAddress); } emit accountSettingsUpdated(); } AccountSettingsModel::RegistrationState AccountSettingsModel::getRegistrationState () const { shared_ptr proxyConfig = CoreManager::getInstance()->getCore()->getDefaultProxyConfig(); return proxyConfig ? mapLinphoneRegistrationStateToUi(proxyConfig->getState()) : RegistrationStateNoProxy; } // ----------------------------------------------------------------------------- QString AccountSettingsModel::getPrimaryUsername () const { return QString::fromStdString( CoreManager::getInstance()->getCore()->createPrimaryContactParsed()->getUsername() ); } void AccountSettingsModel::setPrimaryUsername (const QString &username) { shared_ptr core = CoreManager::getInstance()->getCore(); shared_ptr primary = core->createPrimaryContactParsed(); primary->setUsername(Utils::appStringToCoreString( username.isEmpty() ? APPLICATION_NAME : username )); core->setPrimaryContact(primary->asString()); emit accountSettingsUpdated(); } QString AccountSettingsModel::getPrimaryDisplayName () const { return Utils::coreStringToAppString( CoreManager::getInstance()->getCore()->createPrimaryContactParsed()->getDisplayName() ); } void AccountSettingsModel::setPrimaryDisplayName (const QString &displayName) { shared_ptr core = CoreManager::getInstance()->getCore(); shared_ptr primary = core->createPrimaryContactParsed(); primary->setDisplayName(Utils::appStringToCoreString(displayName)); core->setPrimaryContact(primary->asString()); emit accountSettingsUpdated(); } QString AccountSettingsModel::getPrimarySipAddress () const { return Utils::coreStringToAppString( CoreManager::getInstance()->getCore()->createPrimaryContactParsed()->asString() ); } // ----------------------------------------------------------------------------- QVariantList AccountSettingsModel::getAccounts () const { shared_ptr core = CoreManager::getInstance()->getCore(); QVariantList accounts; { QVariantMap account; account["sipAddress"] = Utils::coreStringToAppString(core->createPrimaryContactParsed()->asStringUriOnly()); account["fullSipAddress"] = Utils::coreStringToAppString(core->createPrimaryContactParsed()->asString()); account["unreadMessageCount"] = core->getUnreadChatMessageCountFromLocal(core->createPrimaryContactParsed()); account["missedCallCount"] = CoreManager::getInstance()->getMissedCallCountFromLocal(account["sipAddress"].toString()); account["proxyConfig"].setValue(nullptr); accounts << account; } for (const auto &proxyConfig : core->getProxyConfigList()) { QVariantMap account; account["sipAddress"] = Utils::coreStringToAppString(proxyConfig->getIdentityAddress()->asStringUriOnly()); account["fullSipAddress"] = Utils::coreStringToAppString(proxyConfig->getIdentityAddress()->asString()); account["proxyConfig"].setValue(proxyConfig); account["unreadMessageCount"] = proxyConfig->getUnreadChatMessageCount(); account["missedCallCount"] = CoreManager::getInstance()->getMissedCallCountFromLocal(account["sipAddress"].toString()); accounts << account; } return accounts; } // ----------------------------------------------------------------------------- void AccountSettingsModel::handleRegistrationStateChanged ( const shared_ptr & proxy, linphone::RegistrationState core ) { Q_UNUSED(proxy) Q_UNUSED(core) emit accountSettingsUpdated(); } linphone-desktop-4.2.5/linphone-app/src/components/settings/AccountSettingsModel.hpp000066400000000000000000000104241376717241300310360ustar00rootroot00000000000000/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef ACCOUNT_SETTINGS_MODEL_H_ #define ACCOUNT_SETTINGS_MODEL_H_ #include #include #include #include #include // ============================================================================= class AccountSettingsModel : public QObject { Q_OBJECT; // Selected proxy config. Q_PROPERTY(QString username READ getUsername WRITE setUsername NOTIFY accountSettingsUpdated); Q_PROPERTY(QString sipAddress READ getUsedSipAddressAsStringUriOnly NOTIFY accountSettingsUpdated); Q_PROPERTY(QString fullSipAddress READ getUsedSipAddressAsString); Q_PROPERTY(RegistrationState registrationState READ getRegistrationState NOTIFY accountSettingsUpdated); // Default info. Q_PROPERTY(QString primaryDisplayName READ getPrimaryDisplayName WRITE setPrimaryDisplayName NOTIFY accountSettingsUpdated); Q_PROPERTY(QString primaryUsername READ getPrimaryUsername WRITE setPrimaryUsername NOTIFY accountSettingsUpdated); Q_PROPERTY(QString primarySipAddress READ getPrimarySipAddress NOTIFY accountSettingsUpdated); Q_PROPERTY(QVariantList accounts READ getAccounts NOTIFY accountSettingsUpdated); public: enum RegistrationState { RegistrationStateRegistered, RegistrationStateNotRegistered, RegistrationStateInProgress, RegistrationStateNoProxy, }; Q_ENUM(RegistrationState); AccountSettingsModel (QObject *parent = Q_NULLPTR); std::shared_ptr getUsedSipAddress () const; void setUsedSipAddress (const std::shared_ptr &address); QString getUsedSipAddressAsStringUriOnly () const; QString getUsedSipAddressAsString () const; bool addOrUpdateProxyConfig (const std::shared_ptr &proxyConfig); Q_INVOKABLE QVariantMap getProxyConfigDescription (const std::shared_ptr &proxyConfig); Q_INVOKABLE void setDefaultProxyConfig (const std::shared_ptr &proxyConfig = nullptr); Q_INVOKABLE void setDefaultProxyConfigFromSipAddress (const QString &sipAddress); Q_INVOKABLE bool addOrUpdateProxyConfig (const std::shared_ptr &proxyConfig, const QVariantMap &data); Q_INVOKABLE void removeProxyConfig (const std::shared_ptr &proxyConfig); Q_INVOKABLE std::shared_ptr createProxyConfig (); Q_INVOKABLE void addAuthInfo ( const std::shared_ptr &authInfo, const QString &password, const QString &userId ); Q_INVOKABLE void eraseAllPasswords (); signals: void accountSettingsUpdated (); void publishPresenceChanged(); private: QString getUsername () const; void setUsername (const QString &username); RegistrationState getRegistrationState () const; // --------------------------------------------------------------------------- QString getPrimaryUsername () const; void setPrimaryUsername (const QString &username); QString getPrimaryDisplayName () const; void setPrimaryDisplayName (const QString &displayName); QString getPrimarySipAddress () const; // --------------------------------------------------------------------------- QVariantList getAccounts () const; // --------------------------------------------------------------------------- void handleRegistrationStateChanged ( const std::shared_ptr &proxyConfig, linphone::RegistrationState state ); }; Q_DECLARE_METATYPE(std::shared_ptr); #endif // ACCOUNT_SETTINGS_MODEL_H_ linphone-desktop-4.2.5/linphone-app/src/components/settings/SettingsModel.cpp000066400000000000000000001216541376717241300275240ustar00rootroot00000000000000/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include #include #include #include #include "app/logger/Logger.hpp" #include "app/paths/Paths.hpp" #include "components/core/CoreManager.hpp" #include "utils/Utils.hpp" #include "utils/MediastreamerUtils.hpp" #include "SettingsModel.hpp" // ============================================================================= using namespace std; namespace { constexpr char DefaultRlsUri[] = "sips:rls@sip.linphone.org"; constexpr char DefaultLogsEmail[] = "linphone-desktop@belledonne-communications.com"; } const string SettingsModel::UiSection("ui"); SettingsModel::SettingsModel (QObject *parent) : QObject(parent) { CoreManager *coreManager = CoreManager::getInstance(); mConfig = coreManager->getCore()->getConfig(); QObject::connect(coreManager->getHandlers().get(), &CoreHandlers::callCreated, this, &SettingsModel::handleCallCreated); QObject::connect(coreManager->getHandlers().get(), &CoreHandlers::callStateChanged, this, &SettingsModel::handleCallStateChanged); configureRlsUri(); } SettingsModel::~SettingsModel() { if(mSimpleCaptureGraph ) { delete mSimpleCaptureGraph; mSimpleCaptureGraph = nullptr; } } void SettingsModel::settingsWindowClosing(void) { onSettingsTabChanged(-1); } //Provides tabbar per-tab setup/teardown mechanism for specific settings views void SettingsModel::onSettingsTabChanged(int idx) { int prevIdx = mCurrentSettingsTab; mCurrentSettingsTab = idx; switch (prevIdx) { case 0://sip break; case 1://audio closeAudioSettings(); break; case 2://video break; case 3://call break; case 4://ui break; case 5://advanced break; default: break; } switch (idx) { case 0://sip break; case 1://audio accessAudioSettings(); break; case 2://video accessVideoSettings(); break; case 3://call break; case 4://ui break; case 5://advanced break; default: break; } } // ============================================================================= // Assistant. // ============================================================================= bool SettingsModel::getUseAppSipAccountEnabled () const { return !!mConfig->getInt(UiSection, "use_app_sip_account_enabled", 1); } void SettingsModel::setUseAppSipAccountEnabled (bool status) { mConfig->setInt(UiSection, "use_app_sip_account_enabled", status); emit useAppSipAccountEnabledChanged(status); } bool SettingsModel::getUseOtherSipAccountEnabled () const { return !!mConfig->getInt(UiSection, "use_other_sip_account_enabled", 1); } void SettingsModel::setUseOtherSipAccountEnabled (bool status) { mConfig->setInt(UiSection, "use_other_sip_account_enabled", status); emit useOtherSipAccountEnabledChanged(status); } bool SettingsModel::getCreateAppSipAccountEnabled () const { return !!mConfig->getInt(UiSection, "create_app_sip_account_enabled", 1); } void SettingsModel::setCreateAppSipAccountEnabled (bool status) { mConfig->setInt(UiSection, "create_app_sip_account_enabled", status); emit createAppSipAccountEnabledChanged(status); } bool SettingsModel::getFetchRemoteConfigurationEnabled () const { return !!mConfig->getInt(UiSection, "fetch_remote_configuration_enabled", 1); } void SettingsModel::setFetchRemoteConfigurationEnabled (bool status) { mConfig->setInt(UiSection, "fetch_remote_configuration_enabled", status); emit fetchRemoteConfigurationEnabledChanged(status); } // --------------------------------------------------------------------------- bool SettingsModel::getAssistantSupportsPhoneNumbers () const { return !!mConfig->getInt(UiSection, "assistant_supports_phone_numbers", 1); } void SettingsModel::setAssistantSupportsPhoneNumbers (bool status) { mConfig->setInt(UiSection, "assistant_supports_phone_numbers", status); emit assistantSupportsPhoneNumbersChanged(status); } // ============================================================================= // Audio. // ============================================================================= void SettingsModel::createCaptureGraph() { if (mSimpleCaptureGraph) { delete mSimpleCaptureGraph; mSimpleCaptureGraph = nullptr; } if (!mSimpleCaptureGraph) { mSimpleCaptureGraph = new MediastreamerUtils::SimpleCaptureGraph(Utils::appStringToCoreString(getCaptureDevice()), Utils::appStringToCoreString(getPlaybackDevice())); } mSimpleCaptureGraph->start(); emit captureGraphRunningChanged(getCaptureGraphRunning()); } //Force a call on the 'detect' method of all audio filters, updating new or removed devices void SettingsModel::accessAudioSettings() { CoreManager::getInstance()->getCore()->reloadSoundDevices(); emit captureDevicesChanged(getCaptureDevices()); emit playbackDevicesChanged(getPlaybackDevices()); emit playbackDeviceChanged(getPlaybackDevice()); emit captureDeviceChanged(getCaptureDevice()); emit ringerDeviceChanged(getRingerDevice()); if (!getIsInCall()) { createCaptureGraph(); } } void SettingsModel::closeAudioSettings() { if (mSimpleCaptureGraph) { if (mSimpleCaptureGraph->isRunning()) { mSimpleCaptureGraph->stop(); } delete mSimpleCaptureGraph; mSimpleCaptureGraph = nullptr; } emit captureGraphRunningChanged(getCaptureGraphRunning()); } bool SettingsModel::getCaptureGraphRunning() { return mSimpleCaptureGraph && mSimpleCaptureGraph->isRunning() && !getIsInCall(); } float SettingsModel::getMicVolume() { float v = 0.0; if (mSimpleCaptureGraph && mSimpleCaptureGraph->isRunning()) { v = mSimpleCaptureGraph->getCaptureVolume(); } return v; } float SettingsModel::getPlaybackGain() const { float dbGain = CoreManager::getInstance()->getCore()->getPlaybackGainDb(); return MediastreamerUtils::dbToLinear(dbGain); } void SettingsModel::setPlaybackGain(float gain) { if (mSimpleCaptureGraph && mSimpleCaptureGraph->isRunning()) { mSimpleCaptureGraph->setPlaybackGain(gain); } } float SettingsModel::getCaptureGain() const { float dbGain = CoreManager::getInstance()->getCore()->getMicGainDb(); return MediastreamerUtils::dbToLinear(dbGain); } void SettingsModel::setCaptureGain(float gain) { if (mSimpleCaptureGraph && mSimpleCaptureGraph->isRunning()) { mSimpleCaptureGraph->setCaptureGain(gain); } } QStringList SettingsModel::getCaptureDevices () const { shared_ptr core = CoreManager::getInstance()->getCore(); QStringList list; for (const auto &device : core->getSoundDevicesList()) { if (core->soundDeviceCanCapture(device)) list << Utils::coreStringToAppString(device); } return list; } QStringList SettingsModel::getPlaybackDevices () const { shared_ptr core = CoreManager::getInstance()->getCore(); QStringList list; for (const auto &device : core->getSoundDevicesList()) { if (core->soundDeviceCanPlayback(device)) { list << Utils::coreStringToAppString(device); } } return list; } // ----------------------------------------------------------------------------- QString SettingsModel::getCaptureDevice () const { return Utils::coreStringToAppString( CoreManager::getInstance()->getCore()->getCaptureDevice() ); } void SettingsModel::setCaptureDevice (const QString &device) { CoreManager::getInstance()->getCore()->setCaptureDevice( Utils::appStringToCoreString(device) ); emit captureDeviceChanged(device); if (mSimpleCaptureGraph && mSimpleCaptureGraph->isRunning()) { createCaptureGraph(); } } // ----------------------------------------------------------------------------- QString SettingsModel::getPlaybackDevice () const { return Utils::coreStringToAppString( CoreManager::getInstance()->getCore()->getPlaybackDevice() ); } void SettingsModel::setPlaybackDevice (const QString &device) { CoreManager::getInstance()->getCore()->setPlaybackDevice( Utils::appStringToCoreString(device) ); emit playbackDeviceChanged(device); if (mSimpleCaptureGraph && mSimpleCaptureGraph->isRunning()) { createCaptureGraph(); } } // ----------------------------------------------------------------------------- QString SettingsModel::getRingerDevice () const { return Utils::coreStringToAppString( CoreManager::getInstance()->getCore()->getRingerDevice() ); } void SettingsModel::setRingerDevice (const QString &device) { CoreManager::getInstance()->getCore()->setRingerDevice( Utils::appStringToCoreString(device) ); emit ringerDeviceChanged(device); } // ----------------------------------------------------------------------------- QString SettingsModel::getRingPath () const { return Utils::coreStringToAppString(CoreManager::getInstance()->getCore()->getRing()); } void SettingsModel::setRingPath (const QString &path) { QString cleanedPath = QDir::cleanPath(path); CoreManager::getInstance()->getCore()->setRing( Utils::appStringToCoreString(cleanedPath) ); emit ringPathChanged(cleanedPath); } // ----------------------------------------------------------------------------- bool SettingsModel::getEchoCancellationEnabled () const { return CoreManager::getInstance()->getCore()->echoCancellationEnabled(); } void SettingsModel::setEchoCancellationEnabled (bool status) { CoreManager::getInstance()->getCore()->enableEchoCancellation(status); emit echoCancellationEnabledChanged(status); } // ----------------------------------------------------------------------------- bool SettingsModel::getShowAudioCodecs () const { return !!mConfig->getInt(UiSection, "show_audio_codecs", 1); } void SettingsModel::setShowAudioCodecs (bool status) { mConfig->setInt(UiSection, "show_audio_codecs", status); emit showAudioCodecsChanged(status); } // ============================================================================= // Video. // ============================================================================= //Force a call on the 'detect' method of all video filters, updating new or removed devices void SettingsModel::accessVideoSettings() { if(!getIsInCall())// TODO : This is a workaround to a crash when reloading video devices while in call. Spotted on Macos. CoreManager::getInstance()->getCore()->reloadVideoDevices(); emit videoDevicesChanged(getVideoDevices()); } QStringList SettingsModel::getVideoDevices () const { QStringList list; for (const auto &device : CoreManager::getInstance()->getCore()->getVideoDevicesList()) list << Utils::coreStringToAppString(device); return list; } // ----------------------------------------------------------------------------- QString SettingsModel::getVideoDevice () const { return Utils::coreStringToAppString( CoreManager::getInstance()->getCore()->getVideoDevice() ); } void SettingsModel::setVideoDevice (const QString &device) { CoreManager::getInstance()->getCore()->setVideoDevice( Utils::appStringToCoreString(device) ); emit videoDeviceChanged(device); } // ----------------------------------------------------------------------------- QString SettingsModel::getVideoPreset () const { return Utils::coreStringToAppString( CoreManager::getInstance()->getCore()->getVideoPreset() ); } void SettingsModel::setVideoPreset (const QString &preset) { CoreManager::getInstance()->getCore()->setVideoPreset( Utils::appStringToCoreString(preset) ); emit videoPresetChanged(preset); } // ----------------------------------------------------------------------------- int SettingsModel::getVideoFramerate () const { return int(CoreManager::getInstance()->getCore()->getPreferredFramerate()); } void SettingsModel::setVideoFramerate (int framerate) { CoreManager::getInstance()->getCore()->setPreferredFramerate(float(framerate)); emit videoFramerateChanged(framerate); } // ----------------------------------------------------------------------------- static inline QVariantMap createMapFromVideoDefinition (const shared_ptr &definition) { QVariantMap map; if (!definition) { Q_ASSERT(!CoreManager::getInstance()->getCore()->videoSupported()); map["name"] = QStringLiteral("Bad EGG"); map["width"] = QStringLiteral("?????"); map["height"] = QStringLiteral("?????"); return map; } map["name"] = Utils::coreStringToAppString(definition->getName()); map["width"] = definition->getWidth(); map["height"] = definition->getHeight(); map["__definition"] = QVariant::fromValue(definition); return map; } QVariantList SettingsModel::getSupportedVideoDefinitions () const { QVariantList list; for (const auto &definition : linphone::Factory::get()->getSupportedVideoDefinitions()) list << createMapFromVideoDefinition(definition); return list; } QVariantMap SettingsModel::getVideoDefinition () const { return createMapFromVideoDefinition(CoreManager::getInstance()->getCore()->getPreferredVideoDefinition()); } void SettingsModel::setVideoDefinition (const QVariantMap &definition) { CoreManager::getInstance()->getCore()->setPreferredVideoDefinition( definition.value("__definition").value>()->clone() ); emit videoDefinitionChanged(definition); } bool SettingsModel::getVideoSupported () const { return CoreManager::getInstance()->getCore()->videoSupported(); } // ----------------------------------------------------------------------------- bool SettingsModel::getShowVideoCodecs () const { return !!mConfig->getInt(UiSection, "show_video_codecs", 1); } void SettingsModel::setShowVideoCodecs (bool status) { mConfig->setInt(UiSection, "show_video_codecs", status); emit showVideoCodecsChanged(status); } // ============================================================================= // Chat & calls. // ============================================================================= bool SettingsModel::getAutoAnswerStatus () const { return !!mConfig->getInt(UiSection, "auto_answer", 0); } void SettingsModel::setAutoAnswerStatus (bool status) { mConfig->setInt(UiSection, "auto_answer", status); emit autoAnswerStatusChanged(status); } // ----------------------------------------------------------------------------- bool SettingsModel::getAutoAnswerVideoStatus () const { return !!mConfig->getInt(UiSection, "auto_answer_with_video", 0); } void SettingsModel::setAutoAnswerVideoStatus (bool status) { mConfig->setInt(UiSection, "auto_answer_with_video", status); emit autoAnswerVideoStatusChanged(status); } // ----------------------------------------------------------------------------- int SettingsModel::getAutoAnswerDelay () const { return mConfig->getInt(UiSection, "auto_answer_delay", 0); } void SettingsModel::setAutoAnswerDelay (int delay) { mConfig->setInt(UiSection, "auto_answer_delay", delay); emit autoAnswerDelayChanged(delay); } // ----------------------------------------------------------------------------- bool SettingsModel::getShowTelKeypadAutomatically () const { return !!mConfig->getInt(UiSection, "show_tel_keypad_automatically", 0); } void SettingsModel::setShowTelKeypadAutomatically (bool status) { mConfig->setInt(UiSection, "show_tel_keypad_automatically", status); emit showTelKeypadAutomaticallyChanged(status); } // ----------------------------------------------------------------------------- bool SettingsModel::getKeepCallsWindowInBackground () const { return !!mConfig->getInt(UiSection, "keep_calls_window_in_background", 0); } void SettingsModel::setKeepCallsWindowInBackground (bool status) { mConfig->setInt(UiSection, "keep_calls_window_in_background", status); emit keepCallsWindowInBackgroundChanged(status); } // ----------------------------------------------------------------------------- bool SettingsModel::getOutgoingCallsEnabled () const { return !!mConfig->getInt(UiSection, "outgoing_calls_enabled", 1); } void SettingsModel::setOutgoingCallsEnabled (bool status) { mConfig->setInt(UiSection, "outgoing_calls_enabled", status); emit outgoingCallsEnabledChanged(status); } // ----------------------------------------------------------------------------- bool SettingsModel::getCallRecorderEnabled () const { return !!mConfig->getInt(UiSection, "call_recorder_enabled", 1); } void SettingsModel::setCallRecorderEnabled (bool status) { mConfig->setInt(UiSection, "call_recorder_enabled", status); emit callRecorderEnabledChanged(status); } // ----------------------------------------------------------------------------- bool SettingsModel::getAutomaticallyRecordCalls () const { return !!mConfig->getInt(UiSection, "automatically_record_calls", 0); } void SettingsModel::setAutomaticallyRecordCalls (bool status) { mConfig->setInt(UiSection, "automatically_record_calls", status); emit automaticallyRecordCallsChanged(status); } // ----------------------------------------------------------------------------- bool SettingsModel::getCallPauseEnabled () const { return !!mConfig->getInt(UiSection, "call_pause_enabled", 1); } void SettingsModel::setCallPauseEnabled (bool status) { mConfig->setInt(UiSection, "call_pause_enabled", status); emit callPauseEnabledChanged(status); } bool SettingsModel::getMuteMicrophoneEnabled () const { return !!mConfig->getInt(UiSection, "mute_microphone_enabled", 1); } void SettingsModel::setMuteMicrophoneEnabled (bool status) { mConfig->setInt(UiSection, "mute_microphone_enabled", status); emit muteMicrophoneEnabledChanged(status); } // ----------------------------------------------------------------------------- bool SettingsModel::getChatEnabled () const { return !!mConfig->getInt(UiSection, "chat_enabled", 1); } void SettingsModel::setChatEnabled (bool status) { mConfig->setInt(UiSection, "chat_enabled", status); emit chatEnabledChanged(status); } // ----------------------------------------------------------------------------- bool SettingsModel::getConferenceEnabled () const { return !!mConfig->getInt(UiSection, "conference_enabled", 1); } void SettingsModel::setConferenceEnabled (bool status) { mConfig->setInt(UiSection, "conference_enabled", status); emit conferenceEnabledChanged(status); } // ----------------------------------------------------------------------------- bool SettingsModel::getChatNotificationSoundEnabled () const { return !!mConfig->getInt(UiSection, "chat_sound_notification_enabled", 1); } void SettingsModel::setChatNotificationSoundEnabled (bool status) { mConfig->setInt(UiSection, "chat_sound_notification_enabled", status); emit chatNotificationSoundEnabledChanged(status); } // ----------------------------------------------------------------------------- QString SettingsModel::getChatNotificationSoundPath () const { static const string defaultFile = linphone::Factory::get()->getSoundResourcesDir() + "/incoming_chat.wav"; return Utils::coreStringToAppString(mConfig->getString(UiSection, "chat_sound_notification_file", defaultFile)); } void SettingsModel::setChatNotificationSoundPath (const QString &path) { QString cleanedPath = QDir::cleanPath(path); mConfig->setString(UiSection, "chat_sound_notification_file", Utils::appStringToCoreString(cleanedPath)); emit chatNotificationSoundPathChanged(cleanedPath); } // ----------------------------------------------------------------------------- QString SettingsModel::getFileTransferUrl () const { return Utils::coreStringToAppString( CoreManager::getInstance()->getCore()->getFileTransferServer() ); } void SettingsModel::setFileTransferUrl (const QString &url) { CoreManager::getInstance()->getCore()->setFileTransferServer( Utils::appStringToCoreString(url) ); emit fileTransferUrlChanged(url); } // ----------------------------------------------------------------------------- bool SettingsModel::getLimeIsSupported () const { return CoreManager::getInstance()->getCore()->limeX3DhAvailable(); } // ----------------------------------------------------------------------------- static inline QVariant buildEncryptionDescription (SettingsModel::MediaEncryption encryption, const char *description) { return QVariantList() << encryption << description; } QVariantList SettingsModel::getSupportedMediaEncryptions () const { shared_ptr core = CoreManager::getInstance()->getCore(); QVariantList list; if (core->mediaEncryptionSupported(linphone::MediaEncryption::SRTP)) list << buildEncryptionDescription(MediaEncryptionSrtp, "SRTP"); if (core->mediaEncryptionSupported(linphone::MediaEncryption::ZRTP)) list << buildEncryptionDescription(MediaEncryptionZrtp, "ZRTP"); if (core->mediaEncryptionSupported(linphone::MediaEncryption::DTLS)) list << buildEncryptionDescription(MediaEncryptionDtls, "DTLS"); return list; } // ----------------------------------------------------------------------------- SettingsModel::MediaEncryption SettingsModel::getMediaEncryption () const { return static_cast( CoreManager::getInstance()->getCore()->getMediaEncryption() ); } void SettingsModel::setMediaEncryption (MediaEncryption encryption) { if (encryption == getMediaEncryption()) return; if (encryption != SettingsModel::MediaEncryptionZrtp) setLimeState(false); CoreManager::getInstance()->getCore()->setMediaEncryption( static_cast(encryption) ); if (mandatoryMediaEncryptionEnabled() && encryption == SettingsModel::MediaEncryptionNone) { //Disable mandatory encryption if none is selected enableMandatoryMediaEncryption(false); } emit mediaEncryptionChanged(encryption); } bool SettingsModel::mandatoryMediaEncryptionEnabled () const { return CoreManager::getInstance()->getCore()->isMediaEncryptionMandatory(); } void SettingsModel::enableMandatoryMediaEncryption(bool mandatory) { if (mandatoryMediaEncryptionEnabled() == mandatory) { return; } CoreManager::getInstance()->getCore()->setMediaEncryptionMandatory(mandatory); if (mandatory && getMediaEncryption() == SettingsModel::MediaEncryptionNone) { //Force to SRTP if mandatory but 'none' was selected setMediaEncryption(SettingsModel::MediaEncryptionSrtp); } else { emit mediaEncryptionChanged(getMediaEncryption()); } } // ----------------------------------------------------------------------------- bool SettingsModel::getLimeState () const { return CoreManager::getInstance()->getCore()->limeX3DhEnabled(); } void SettingsModel::setLimeState (const bool& state) { if (state == getLimeState()) return; if (state) setMediaEncryption(SettingsModel::MediaEncryptionZrtp); CoreManager::getInstance()->getCore()->enableLimeX3Dh(!state); emit limeStateChanged(state); } // ----------------------------------------------------------------------------- bool SettingsModel::getContactsEnabled () const { return !!mConfig->getInt(UiSection, "contacts_enabled", 1); } void SettingsModel::setContactsEnabled (bool status) { mConfig->setInt(UiSection, "contacts_enabled", status); emit contactsEnabledChanged(status); } // ============================================================================= // Network. // ============================================================================= bool SettingsModel::getShowNetworkSettings () const { return !!mConfig->getInt(UiSection, "show_network_settings", 1); } void SettingsModel::setShowNetworkSettings (bool status) { mConfig->setInt(UiSection, "show_network_settings", status); emit showNetworkSettingsChanged(status); } // ----------------------------------------------------------------------------- bool SettingsModel::getUseSipInfoForDtmfs () const { return CoreManager::getInstance()->getCore()->getUseInfoForDtmf(); } void SettingsModel::setUseSipInfoForDtmfs (bool status) { shared_ptr core = CoreManager::getInstance()->getCore(); if (status) { core->setUseRfc2833ForDtmf(false); core->setUseInfoForDtmf(true); } else { core->setUseInfoForDtmf(false); core->setUseRfc2833ForDtmf(true); } emit dtmfsProtocolChanged(); } // ----------------------------------------------------------------------------- bool SettingsModel::getUseRfc2833ForDtmfs () const { return CoreManager::getInstance()->getCore()->getUseRfc2833ForDtmf(); } void SettingsModel::setUseRfc2833ForDtmfs (bool status) { shared_ptr core = CoreManager::getInstance()->getCore(); if (status) { core->setUseInfoForDtmf(false); core->setUseRfc2833ForDtmf(true); } else { core->setUseRfc2833ForDtmf(false); core->setUseInfoForDtmf(true); } emit dtmfsProtocolChanged(); } // ----------------------------------------------------------------------------- bool SettingsModel::getIpv6Enabled () const { return CoreManager::getInstance()->getCore()->ipv6Enabled(); } void SettingsModel::setIpv6Enabled (bool status) { CoreManager::getInstance()->getCore()->enableIpv6(status); emit ipv6EnabledChanged(status); } // ----------------------------------------------------------------------------- int SettingsModel::getDownloadBandwidth () const { return CoreManager::getInstance()->getCore()->getDownloadBandwidth(); } void SettingsModel::setDownloadBandwidth (int bandwidth) { CoreManager::getInstance()->getCore()->setDownloadBandwidth(bandwidth); emit downloadBandWidthChanged(getDownloadBandwidth()); } // ----------------------------------------------------------------------------- int SettingsModel::getUploadBandwidth () const { return CoreManager::getInstance()->getCore()->getUploadBandwidth(); } void SettingsModel::setUploadBandwidth (int bandwidth) { CoreManager::getInstance()->getCore()->setUploadBandwidth(bandwidth); emit uploadBandWidthChanged(getUploadBandwidth()); } // ----------------------------------------------------------------------------- bool SettingsModel::getAdaptiveRateControlEnabled () const { return CoreManager::getInstance()->getCore()->adaptiveRateControlEnabled(); } void SettingsModel::setAdaptiveRateControlEnabled (bool status) { CoreManager::getInstance()->getCore()->enableAdaptiveRateControl(status); emit adaptiveRateControlEnabledChanged(status); } // ----------------------------------------------------------------------------- int SettingsModel::getTcpPort () const { return CoreManager::getInstance()->getCore()->getTransports()->getTcpPort(); } void SettingsModel::setTcpPort (int port) { shared_ptr core = CoreManager::getInstance()->getCore(); shared_ptr transports = core->getTransports(); transports->setTcpPort(port); core->setTransports(transports); emit tcpPortChanged(port); } // ----------------------------------------------------------------------------- int SettingsModel::getUdpPort () const { return CoreManager::getInstance()->getCore()->getTransports()->getUdpPort(); } void SettingsModel::setUdpPort (int port) { shared_ptr core = CoreManager::getInstance()->getCore(); shared_ptr transports = core->getTransports(); transports->setUdpPort(port); core->setTransports(transports); emit udpPortChanged(port); } // ----------------------------------------------------------------------------- QList SettingsModel::getAudioPortRange () const { shared_ptr range = CoreManager::getInstance()->getCore()->getAudioPortsRange(); return QList() << range->getMin() << range->getMax(); } void SettingsModel::setAudioPortRange (const QList &range) { shared_ptr core = CoreManager::getInstance()->getCore(); int a = range[0]; int b = range[1]; if (b == -1) core->setAudioPort(a); else core->setAudioPortRange(a, b); emit audioPortRangeChanged(a, b); } // ----------------------------------------------------------------------------- QList SettingsModel::getVideoPortRange () const { shared_ptr range = CoreManager::getInstance()->getCore()->getVideoPortsRange(); return QList() << range->getMin() << range->getMax(); } void SettingsModel::setVideoPortRange (const QList &range) { shared_ptr core = CoreManager::getInstance()->getCore(); int a = range[0]; int b = range[1]; if (b == -1) core->setVideoPort(a); else core->setVideoPortRange(a, b); emit videoPortRangeChanged(a, b); } // ----------------------------------------------------------------------------- bool SettingsModel::getIceEnabled () const { return CoreManager::getInstance()->getCore()->getNatPolicy()->iceEnabled(); } void SettingsModel::setIceEnabled (bool status) { shared_ptr natPolicy = CoreManager::getInstance()->getCore()->getNatPolicy(); natPolicy->enableIce(status); natPolicy->enableStun(status); emit iceEnabledChanged(status); } // ----------------------------------------------------------------------------- bool SettingsModel::getTurnEnabled () const { return CoreManager::getInstance()->getCore()->getNatPolicy()->turnEnabled(); } void SettingsModel::setTurnEnabled (bool status) { CoreManager::getInstance()->getCore()->getNatPolicy()->enableTurn(status); emit turnEnabledChanged(status); } // ----------------------------------------------------------------------------- QString SettingsModel::getStunServer () const { return Utils::coreStringToAppString( CoreManager::getInstance()->getCore()->getNatPolicy()->getStunServer() ); } void SettingsModel::setStunServer (const QString &stunServer) { CoreManager::getInstance()->getCore()->getNatPolicy()->setStunServer( Utils::appStringToCoreString(stunServer) ); } // ----------------------------------------------------------------------------- QString SettingsModel::getTurnUser () const { return Utils::coreStringToAppString( CoreManager::getInstance()->getCore()->getNatPolicy()->getStunServerUsername() ); } void SettingsModel::setTurnUser (const QString &user) { CoreManager::getInstance()->getCore()->getNatPolicy()->setStunServerUsername( Utils::appStringToCoreString(user) ); emit turnUserChanged(user); } // ----------------------------------------------------------------------------- QString SettingsModel::getTurnPassword () const { shared_ptr core(CoreManager::getInstance()->getCore()); shared_ptr natPolicy(core->getNatPolicy()); shared_ptr authInfo(core->findAuthInfo( "", natPolicy->getStunServerUsername(), natPolicy->getStunServer() )); return authInfo ? Utils::coreStringToAppString(authInfo->getPassword()) : QString(""); } void SettingsModel::setTurnPassword (const QString &password) { shared_ptr core(CoreManager::getInstance()->getCore()); shared_ptr natPolicy(core->getNatPolicy()); const string &turnUser(natPolicy->getStunServerUsername()); shared_ptr authInfo(core->findAuthInfo("", turnUser, natPolicy->getStunServer())); if (authInfo) { shared_ptr clonedAuthInfo(authInfo->clone()); clonedAuthInfo->setPassword(Utils::appStringToCoreString(password)); core->addAuthInfo(clonedAuthInfo); core->removeAuthInfo(authInfo); } else core->addAuthInfo(linphone::Factory::get()->createAuthInfo( turnUser, turnUser, Utils::appStringToCoreString(password), "", "", "" )); emit turnPasswordChanged(password); } // ----------------------------------------------------------------------------- int SettingsModel::getDscpSip () const { return CoreManager::getInstance()->getCore()->getSipDscp(); } void SettingsModel::setDscpSip (int dscp) { CoreManager::getInstance()->getCore()->setSipDscp(dscp); emit dscpSipChanged(dscp); } int SettingsModel::getDscpAudio () const { return CoreManager::getInstance()->getCore()->getAudioDscp(); } void SettingsModel::setDscpAudio (int dscp) { CoreManager::getInstance()->getCore()->setAudioDscp(dscp); emit dscpAudioChanged(dscp); } int SettingsModel::getDscpVideo () const { return CoreManager::getInstance()->getCore()->getVideoDscp(); } void SettingsModel::setDscpVideo (int dscp) { CoreManager::getInstance()->getCore()->setVideoDscp(dscp); emit dscpVideoChanged(dscp); } // ----------------------------------------------------------------------------- bool SettingsModel::getRlsUriEnabled () const { return !!mConfig->getInt(UiSection, "rls_uri_enabled", true); } void SettingsModel::setRlsUriEnabled (bool status) { mConfig->setInt(UiSection, "rls_uri_enabled", status); mConfig->setString("sip", "rls_uri", status ? DefaultRlsUri : ""); emit rlsUriEnabledChanged(status); } static string getRlsUriDomain () { static string domain; if (!domain.empty()) return domain; shared_ptr linphoneAddress = CoreManager::getInstance()->getCore()->createAddress(DefaultRlsUri); Q_CHECK_PTR(linphoneAddress); domain = linphoneAddress->getDomain(); return domain; } void SettingsModel::configureRlsUri () { // Ensure rls uri is empty. if (!getRlsUriEnabled()) { mConfig->setString("sip", "rls_uri", ""); return; } // Set rls uri if necessary. const string domain = getRlsUriDomain(); for (const auto &proxyConfig : CoreManager::getInstance()->getCore()->getProxyConfigList()) if (proxyConfig->getDomain() == domain) { mConfig->setString("sip", "rls_uri", DefaultRlsUri); return; } mConfig->setString("sip", "rls_uri", ""); } void SettingsModel::configureRlsUri (const shared_ptr &proxyConfig) { if (!getRlsUriEnabled()) { mConfig->setString("sip", "rls_uri", ""); return; } const string domain = getRlsUriDomain(); if (proxyConfig->getDomain() == domain) { mConfig->setString("sip", "rls_uri", DefaultRlsUri); return; } mConfig->setString("sip", "rls_uri", ""); } // ============================================================================= // UI. // ============================================================================= QString SettingsModel::getSavedScreenshotsFolder () const { return QDir::cleanPath( Utils::coreStringToAppString( mConfig->getString(UiSection, "saved_screenshots_folder", Paths::getCapturesDirPath()) ) ) + QDir::separator(); } void SettingsModel::setSavedScreenshotsFolder (const QString &folder) { QString cleanedFolder = QDir::cleanPath(folder) + QDir::separator(); mConfig->setString(UiSection, "saved_screenshots_folder", Utils::appStringToCoreString(cleanedFolder)); emit savedScreenshotsFolderChanged(cleanedFolder); } // ----------------------------------------------------------------------------- static inline string getLegacySavedCallsFolder (const shared_ptr &config) { return config->getString(SettingsModel::UiSection, "saved_videos_folder", Paths::getCapturesDirPath()); } QString SettingsModel::getSavedCallsFolder () const { return QDir::cleanPath( Utils::coreStringToAppString( mConfig->getString(UiSection, "saved_calls_folder", getLegacySavedCallsFolder(mConfig)) ) ) + QDir::separator(); } void SettingsModel::setSavedCallsFolder (const QString &folder) { QString cleanedFolder = QDir::cleanPath(folder) + QDir::separator(); mConfig->setString(UiSection, "saved_calls_folder", Utils::appStringToCoreString(cleanedFolder)); emit savedCallsFolderChanged(cleanedFolder); } // ----------------------------------------------------------------------------- QString SettingsModel::getDownloadFolder () const { return QDir::cleanPath( Utils::coreStringToAppString( mConfig->getString(UiSection, "download_folder", Paths::getDownloadDirPath()) ) ) + QDir::separator(); } void SettingsModel::setDownloadFolder (const QString &folder) { QString cleanedFolder = QDir::cleanPath(folder) + QDir::separator(); mConfig->setString(UiSection, "download_folder", Utils::appStringToCoreString(cleanedFolder)); emit downloadFolderChanged(cleanedFolder); } // ----------------------------------------------------------------------------- QString SettingsModel::getRemoteProvisioning () const { return Utils::coreStringToAppString(CoreManager::getInstance()->getCore()->getProvisioningUri()); } void SettingsModel::setRemoteProvisioning (const QString &remoteProvisioning) { if (!CoreManager::getInstance()->getCore()->setProvisioningUri(Utils::appStringToCoreString(remoteProvisioning))) emit remoteProvisioningChanged(remoteProvisioning); else emit remoteProvisioningNotChanged(remoteProvisioning); } // ----------------------------------------------------------------------------- bool SettingsModel::getExitOnClose () const { return !!mConfig->getInt(UiSection, "exit_on_close", 0); } void SettingsModel::setExitOnClose (bool value) { mConfig->setInt(UiSection, "exit_on_close", value); emit exitOnCloseChanged(value); } // ============================================================================= // Advanced. // ============================================================================= QString SettingsModel::getLogsFolder () const { return getLogsFolder(mConfig); } void SettingsModel::setLogsFolder (const QString &folder) { // Copy all logs files in the new folder path to keep trace of old logs std::string logPath = Utils::appStringToCoreString(folder); QDir oldDirectory(Utils::coreStringToAppString(CoreManager::getInstance()->getCore()->getLogCollectionPath())); QFileInfoList logsFiles = oldDirectory.entryInfoList(QStringList("*.log"));// Get all log files for(int i = 0 ; i < logsFiles.size() ; ++i){ int count = 0; QString fileName = logsFiles[i].fileName(); while( QFile::exists(folder+QDir::separator()+fileName))// assure unicity of backup files fileName = logsFiles[i].baseName()+"_"+QString::number(++count)+"."+logsFiles[i].completeSuffix(); if(QFile::copy(logsFiles[i].filePath(), folder+QDir::separator()+fileName)) QFile::remove(logsFiles[i].filePath()); } mConfig->setString(UiSection, "logs_folder", logPath); // Update configuration file CoreManager::getInstance()->getCore()->setLogCollectionPath(logPath); // Update Core to the new path. Liblinphone should update it. emit logsFolderChanged(folder); } // ----------------------------------------------------------------------------- QString SettingsModel::getLogsUploadUrl () const { return Utils::coreStringToAppString( CoreManager::getInstance()->getCore()->getLogCollectionUploadServerUrl() ); } void SettingsModel::setLogsUploadUrl (const QString &url) { CoreManager::getInstance()->getCore()->setLogCollectionUploadServerUrl( Utils::appStringToCoreString(url) ); emit logsUploadUrlChanged(getLogsUploadUrl()); } // ----------------------------------------------------------------------------- bool SettingsModel::getLogsEnabled () const { return getLogsEnabled(mConfig); } void SettingsModel::setLogsEnabled (bool status) { mConfig->setInt(UiSection, "logs_enabled", status); Logger::getInstance()->enable(status); emit logsEnabledChanged(status); } // --------------------------------------------------------------------------- QString SettingsModel::getLogsEmail () const { return Utils::coreStringToAppString( mConfig->getString(UiSection, "logs_email", DefaultLogsEmail) ); } void SettingsModel::setLogsEmail (const QString &email) { mConfig->setString(UiSection, "logs_email", Utils::appStringToCoreString(email)); emit logsEmailChanged(email); } // --------------------------------------------------------------------------- QString SettingsModel::getLogsFolder (const shared_ptr &config) { return Utils::coreStringToAppString(config ? config->getString(UiSection, "logs_folder", Paths::getLogsDirPath()) : Paths::getLogsDirPath()); } bool SettingsModel::getLogsEnabled (const shared_ptr &config) { return config ? config->getInt(UiSection, "logs_enabled", false) : true; } // --------------------------------------------------------------------------- bool SettingsModel::getDeveloperSettingsEnabled () const { #ifdef DEBUG return !!mConfig->getInt(UiSection, "developer_settings", 0); #else return false; #endif // ifdef DEBUG } void SettingsModel::setDeveloperSettingsEnabled (bool status) { #ifdef DEBUG mConfig->setInt(UiSection, "developer_settings", status); emit developerSettingsEnabledChanged(status); #else Q_UNUSED(status) qWarning() << QStringLiteral("Unable to change developer settings mode in release version."); #endif // ifdef DEBUG } void SettingsModel::handleCallCreated(const shared_ptr &) { emit isInCallChanged(getIsInCall()); } void SettingsModel::handleCallStateChanged(const shared_ptr &, linphone::Call::State) { emit isInCallChanged(getIsInCall()); } bool SettingsModel::getIsInCall() const { return CoreManager::getInstance()->getCore()->getCallsNb() != 0; } linphone-desktop-4.2.5/linphone-app/src/components/settings/SettingsModel.hpp000066400000000000000000000555421376717241300275330ustar00rootroot00000000000000/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef SETTINGS_MODEL_H_ #define SETTINGS_MODEL_H_ #include #include #include #include #include "components/core/CoreHandlers.hpp" // ============================================================================= class SettingsModel : public QObject { Q_OBJECT // =========================================================================== // PROPERTIES. // =========================================================================== // Assistant. ---------------------------------------------------------------- Q_PROPERTY(bool createAppSipAccountEnabled READ getCreateAppSipAccountEnabled WRITE setCreateAppSipAccountEnabled NOTIFY createAppSipAccountEnabledChanged) Q_PROPERTY(bool fetchRemoteConfigurationEnabled READ getFetchRemoteConfigurationEnabled WRITE setFetchRemoteConfigurationEnabled NOTIFY fetchRemoteConfigurationEnabledChanged) Q_PROPERTY(bool useAppSipAccountEnabled READ getUseAppSipAccountEnabled WRITE setUseAppSipAccountEnabled NOTIFY useAppSipAccountEnabledChanged) Q_PROPERTY(bool useOtherSipAccountEnabled READ getUseOtherSipAccountEnabled WRITE setUseOtherSipAccountEnabled NOTIFY useOtherSipAccountEnabledChanged) Q_PROPERTY(bool assistantSupportsPhoneNumbers READ getAssistantSupportsPhoneNumbers WRITE setAssistantSupportsPhoneNumbers NOTIFY assistantSupportsPhoneNumbersChanged) // Audio. -------------------------------------------------------------------- Q_PROPERTY(bool captureGraphRunning READ getCaptureGraphRunning NOTIFY captureGraphRunningChanged) Q_PROPERTY(QStringList captureDevices READ getCaptureDevices NOTIFY captureDevicesChanged) Q_PROPERTY(QStringList playbackDevices READ getPlaybackDevices NOTIFY playbackDevicesChanged) Q_PROPERTY(float playbackGain READ getPlaybackGain WRITE setPlaybackGain NOTIFY playbackGainChanged) Q_PROPERTY(float captureGain READ getCaptureGain WRITE setCaptureGain NOTIFY captureGainChanged) Q_PROPERTY(QString captureDevice READ getCaptureDevice WRITE setCaptureDevice NOTIFY captureDeviceChanged) Q_PROPERTY(QString playbackDevice READ getPlaybackDevice WRITE setPlaybackDevice NOTIFY playbackDeviceChanged) Q_PROPERTY(QString ringerDevice READ getRingerDevice WRITE setRingerDevice NOTIFY ringerDeviceChanged) Q_PROPERTY(QString ringPath READ getRingPath WRITE setRingPath NOTIFY ringPathChanged) Q_PROPERTY(bool echoCancellationEnabled READ getEchoCancellationEnabled WRITE setEchoCancellationEnabled NOTIFY echoCancellationEnabledChanged) Q_PROPERTY(bool showAudioCodecs READ getShowAudioCodecs WRITE setShowAudioCodecs NOTIFY showAudioCodecsChanged) // Video. -------------------------------------------------------------------- Q_PROPERTY(QStringList videoDevices READ getVideoDevices NOTIFY videoDevicesChanged) Q_PROPERTY(QString videoDevice READ getVideoDevice WRITE setVideoDevice NOTIFY videoDeviceChanged) Q_PROPERTY(QString videoPreset READ getVideoPreset WRITE setVideoPreset NOTIFY videoPresetChanged) Q_PROPERTY(int videoFramerate READ getVideoFramerate WRITE setVideoFramerate NOTIFY videoFramerateChanged) Q_PROPERTY(QVariantList supportedVideoDefinitions READ getSupportedVideoDefinitions CONSTANT) Q_PROPERTY(QVariantMap videoDefinition READ getVideoDefinition WRITE setVideoDefinition NOTIFY videoDefinitionChanged) Q_PROPERTY(bool videoSupported READ getVideoSupported CONSTANT) Q_PROPERTY(bool showVideoCodecs READ getShowVideoCodecs WRITE setShowVideoCodecs NOTIFY showVideoCodecsChanged) // Chat & calls. ------------------------------------------------------------- Q_PROPERTY(bool autoAnswerStatus READ getAutoAnswerStatus WRITE setAutoAnswerStatus NOTIFY autoAnswerStatusChanged) Q_PROPERTY(bool autoAnswerVideoStatus READ getAutoAnswerVideoStatus WRITE setAutoAnswerVideoStatus NOTIFY autoAnswerVideoStatusChanged) Q_PROPERTY(int autoAnswerDelay READ getAutoAnswerDelay WRITE setAutoAnswerDelay NOTIFY autoAnswerDelayChanged) Q_PROPERTY(bool showTelKeypadAutomatically READ getShowTelKeypadAutomatically WRITE setShowTelKeypadAutomatically NOTIFY showTelKeypadAutomaticallyChanged) Q_PROPERTY(bool keepCallsWindowInBackground READ getKeepCallsWindowInBackground WRITE setKeepCallsWindowInBackground NOTIFY keepCallsWindowInBackgroundChanged) Q_PROPERTY(bool outgoingCallsEnabled READ getOutgoingCallsEnabled WRITE setOutgoingCallsEnabled NOTIFY outgoingCallsEnabledChanged) Q_PROPERTY(bool callRecorderEnabled READ getCallRecorderEnabled WRITE setCallRecorderEnabled NOTIFY callRecorderEnabledChanged) Q_PROPERTY(bool automaticallyRecordCalls READ getAutomaticallyRecordCalls WRITE setAutomaticallyRecordCalls NOTIFY automaticallyRecordCallsChanged) Q_PROPERTY(bool callPauseEnabled READ getCallPauseEnabled WRITE setCallPauseEnabled NOTIFY callPauseEnabledChanged) Q_PROPERTY(bool muteMicrophoneEnabled READ getMuteMicrophoneEnabled WRITE setMuteMicrophoneEnabled NOTIFY muteMicrophoneEnabledChanged) Q_PROPERTY(bool chatEnabled READ getChatEnabled WRITE setChatEnabled NOTIFY chatEnabledChanged) Q_PROPERTY(bool conferenceEnabled READ getConferenceEnabled WRITE setConferenceEnabled NOTIFY conferenceEnabledChanged) Q_PROPERTY(bool chatNotificationSoundEnabled READ getChatNotificationSoundEnabled WRITE setChatNotificationSoundEnabled NOTIFY chatNotificationSoundEnabledChanged) Q_PROPERTY(QString chatNotificationSoundPath READ getChatNotificationSoundPath WRITE setChatNotificationSoundPath NOTIFY chatNotificationSoundPathChanged) Q_PROPERTY(QString fileTransferUrl READ getFileTransferUrl WRITE setFileTransferUrl NOTIFY fileTransferUrlChanged) Q_PROPERTY(bool limeIsSupported READ getLimeIsSupported CONSTANT) Q_PROPERTY(QVariantList supportedMediaEncryptions READ getSupportedMediaEncryptions CONSTANT) Q_PROPERTY(MediaEncryption mediaEncryption READ getMediaEncryption WRITE setMediaEncryption NOTIFY mediaEncryptionChanged) Q_PROPERTY(bool mediaEncryptionMandatory READ mandatoryMediaEncryptionEnabled WRITE enableMandatoryMediaEncryption NOTIFY mediaEncryptionChanged) Q_PROPERTY(bool limeState READ getLimeState WRITE setLimeState NOTIFY limeStateChanged) Q_PROPERTY(bool contactsEnabled READ getContactsEnabled WRITE setContactsEnabled NOTIFY contactsEnabledChanged) // Network. ------------------------------------------------------------------ Q_PROPERTY(bool showNetworkSettings READ getShowNetworkSettings WRITE setShowNetworkSettings NOTIFY showNetworkSettingsChanged) Q_PROPERTY(bool useSipInfoForDtmfs READ getUseSipInfoForDtmfs WRITE setUseSipInfoForDtmfs NOTIFY dtmfsProtocolChanged) Q_PROPERTY(bool useRfc2833ForDtmfs READ getUseRfc2833ForDtmfs WRITE setUseRfc2833ForDtmfs NOTIFY dtmfsProtocolChanged) Q_PROPERTY(bool ipv6Enabled READ getIpv6Enabled WRITE setIpv6Enabled NOTIFY ipv6EnabledChanged) Q_PROPERTY(int downloadBandwidth READ getDownloadBandwidth WRITE setDownloadBandwidth NOTIFY downloadBandWidthChanged) Q_PROPERTY(int uploadBandwidth READ getUploadBandwidth WRITE setUploadBandwidth NOTIFY uploadBandWidthChanged) Q_PROPERTY( bool adaptiveRateControlEnabled READ getAdaptiveRateControlEnabled WRITE setAdaptiveRateControlEnabled NOTIFY adaptiveRateControlEnabledChanged ) Q_PROPERTY(int tcpPort READ getTcpPort WRITE setTcpPort NOTIFY tcpPortChanged) Q_PROPERTY(int udpPort READ getUdpPort WRITE setUdpPort NOTIFY udpPortChanged) Q_PROPERTY(QList audioPortRange READ getAudioPortRange WRITE setAudioPortRange NOTIFY audioPortRangeChanged) Q_PROPERTY(QList videoPortRange READ getVideoPortRange WRITE setVideoPortRange NOTIFY videoPortRangeChanged) Q_PROPERTY(bool iceEnabled READ getIceEnabled WRITE setIceEnabled NOTIFY iceEnabledChanged) Q_PROPERTY(bool turnEnabled READ getTurnEnabled WRITE setTurnEnabled NOTIFY turnEnabledChanged) Q_PROPERTY(QString stunServer READ getStunServer WRITE setStunServer NOTIFY stunServerChanged) Q_PROPERTY(QString turnUser READ getTurnUser WRITE setTurnUser NOTIFY turnUserChanged) Q_PROPERTY(QString turnPassword READ getTurnPassword WRITE setTurnPassword NOTIFY turnPasswordChanged) Q_PROPERTY(int dscpSip READ getDscpSip WRITE setDscpSip NOTIFY dscpSipChanged) Q_PROPERTY(int dscpAudio READ getDscpAudio WRITE setDscpAudio NOTIFY dscpAudioChanged) Q_PROPERTY(int dscpVideo READ getDscpVideo WRITE setDscpVideo NOTIFY dscpVideoChanged) Q_PROPERTY(bool rlsUriEnabled READ getRlsUriEnabled WRITE setRlsUriEnabled NOTIFY rlsUriEnabledChanged) // UI. ----------------------------------------------------------------------- Q_PROPERTY(QString remoteProvisioning READ getRemoteProvisioning WRITE setRemoteProvisioning NOTIFY remoteProvisioningChanged) Q_PROPERTY(QString savedScreenshotsFolder READ getSavedScreenshotsFolder WRITE setSavedScreenshotsFolder NOTIFY savedScreenshotsFolderChanged) Q_PROPERTY(QString savedCallsFolder READ getSavedCallsFolder WRITE setSavedCallsFolder NOTIFY savedCallsFolderChanged) Q_PROPERTY(QString downloadFolder READ getDownloadFolder WRITE setDownloadFolder NOTIFY downloadFolderChanged) Q_PROPERTY(bool exitOnClose READ getExitOnClose WRITE setExitOnClose NOTIFY exitOnCloseChanged) // Advanced. ----------------------------------------------------------------- Q_PROPERTY(QString logsFolder READ getLogsFolder WRITE setLogsFolder NOTIFY logsFolderChanged) Q_PROPERTY(QString logsUploadUrl READ getLogsUploadUrl WRITE setLogsUploadUrl NOTIFY logsUploadUrlChanged) Q_PROPERTY(bool logsEnabled READ getLogsEnabled WRITE setLogsEnabled NOTIFY logsEnabledChanged) Q_PROPERTY(QString logsEmail READ getLogsEmail WRITE setLogsEmail NOTIFY logsEmailChanged) Q_PROPERTY(bool developerSettingsEnabled READ getDeveloperSettingsEnabled WRITE setDeveloperSettingsEnabled NOTIFY developerSettingsEnabledChanged) Q_PROPERTY(bool isInCall READ getIsInCall NOTIFY isInCallChanged) public: enum MediaEncryption { MediaEncryptionNone = int(linphone::MediaEncryption::None), MediaEncryptionDtls = int(linphone::MediaEncryption::DTLS), MediaEncryptionSrtp = int(linphone::MediaEncryption::SRTP), MediaEncryptionZrtp = int(linphone::MediaEncryption::ZRTP) }; Q_ENUM(MediaEncryption) SettingsModel (QObject *parent = Q_NULLPTR); virtual ~SettingsModel (); // =========================================================================== // METHODS. // =========================================================================== Q_INVOKABLE void onSettingsTabChanged(int idx); Q_INVOKABLE void settingsWindowClosing(void); // Assistant. ---------------------------------------------------------------- bool getCreateAppSipAccountEnabled () const; void setCreateAppSipAccountEnabled (bool status); bool getFetchRemoteConfigurationEnabled () const; void setFetchRemoteConfigurationEnabled (bool status); bool getUseAppSipAccountEnabled () const; void setUseAppSipAccountEnabled (bool status); bool getUseOtherSipAccountEnabled () const; void setUseOtherSipAccountEnabled (bool status); bool getAssistantSupportsPhoneNumbers () const; void setAssistantSupportsPhoneNumbers (bool status); // Audio. -------------------------------------------------------------------- void createCaptureGraph(); bool getCaptureGraphRunning(); void accessAudioSettings(); void closeAudioSettings(); Q_INVOKABLE float getMicVolume(); float getPlaybackGain() const; void setPlaybackGain(float gain); float getCaptureGain() const; void setCaptureGain(float gain); QStringList getCaptureDevices () const; QStringList getPlaybackDevices () const; QString getCaptureDevice () const; void setCaptureDevice (const QString &device); QString getPlaybackDevice () const; void setPlaybackDevice (const QString &device); QString getRingerDevice () const; void setRingerDevice (const QString &device); QString getRingPath () const; void setRingPath (const QString &path); bool getEchoCancellationEnabled () const; void setEchoCancellationEnabled (bool status); bool getShowAudioCodecs () const; void setShowAudioCodecs (bool status); // Video. -------------------------------------------------------------------- //Called from qml when accessing audio settings panel Q_INVOKABLE void accessVideoSettings(); QStringList getVideoDevices () const; QString getVideoDevice () const; void setVideoDevice (const QString &device); QString getVideoPreset () const; void setVideoPreset (const QString &preset); int getVideoFramerate () const; void setVideoFramerate (int framerate); QVariantList getSupportedVideoDefinitions () const; QVariantMap getVideoDefinition () const; void setVideoDefinition (const QVariantMap &definition); bool getVideoSupported () const; bool getShowVideoCodecs () const; void setShowVideoCodecs (bool status); // Chat & calls. ------------------------------------------------------------- bool getAutoAnswerStatus () const; void setAutoAnswerStatus (bool status); bool getAutoAnswerVideoStatus () const; void setAutoAnswerVideoStatus (bool status); int getAutoAnswerDelay () const; void setAutoAnswerDelay (int delay); bool getShowTelKeypadAutomatically () const; void setShowTelKeypadAutomatically (bool status); bool getKeepCallsWindowInBackground () const; void setKeepCallsWindowInBackground (bool status); bool getOutgoingCallsEnabled () const; void setOutgoingCallsEnabled (bool status); bool getCallRecorderEnabled () const; void setCallRecorderEnabled (bool status); bool getAutomaticallyRecordCalls () const; void setAutomaticallyRecordCalls (bool status); bool getCallPauseEnabled () const; void setCallPauseEnabled (bool status); bool getMuteMicrophoneEnabled () const; void setMuteMicrophoneEnabled (bool status); bool getChatEnabled () const; void setChatEnabled (bool status); bool getConferenceEnabled () const; void setConferenceEnabled (bool status); bool getChatNotificationSoundEnabled () const; void setChatNotificationSoundEnabled (bool status); QString getChatNotificationSoundPath () const; void setChatNotificationSoundPath (const QString &path); QString getFileTransferUrl () const; void setFileTransferUrl (const QString &url); bool getLimeIsSupported () const; QVariantList getSupportedMediaEncryptions () const; MediaEncryption getMediaEncryption () const; void setMediaEncryption (MediaEncryption encryption); bool mandatoryMediaEncryptionEnabled () const; void enableMandatoryMediaEncryption(bool mandatory); bool getLimeState () const; void setLimeState (const bool& state); bool getContactsEnabled () const; void setContactsEnabled (bool status); // Network. ------------------------------------------------------------------ bool getShowNetworkSettings () const; void setShowNetworkSettings (bool status); bool getUseSipInfoForDtmfs () const; void setUseSipInfoForDtmfs (bool status); bool getUseRfc2833ForDtmfs () const; void setUseRfc2833ForDtmfs (bool status); bool getIpv6Enabled () const; void setIpv6Enabled (bool status); int getDownloadBandwidth () const; void setDownloadBandwidth (int bandwidth); int getUploadBandwidth () const; void setUploadBandwidth (int bandwidth); bool getAdaptiveRateControlEnabled () const; void setAdaptiveRateControlEnabled (bool status); int getTcpPort () const; void setTcpPort (int port); int getUdpPort () const; void setUdpPort (int port); QList getAudioPortRange () const; void setAudioPortRange (const QList &range); QList getVideoPortRange () const; void setVideoPortRange (const QList &range); bool getIceEnabled () const; void setIceEnabled (bool status); bool getTurnEnabled () const; void setTurnEnabled (bool status); QString getStunServer () const; void setStunServer (const QString &stunServer); QString getTurnUser () const; void setTurnUser (const QString &user); QString getTurnPassword () const; void setTurnPassword (const QString &password); int getDscpSip () const; void setDscpSip (int dscp); int getDscpAudio () const; void setDscpAudio (int dscp); int getDscpVideo () const; void setDscpVideo (int dscp); bool getRlsUriEnabled () const; void setRlsUriEnabled (bool status); void configureRlsUri (); void configureRlsUri (const std::shared_ptr &proxyConfig); // UI. ----------------------------------------------------------------------- QString getSavedScreenshotsFolder () const; void setSavedScreenshotsFolder (const QString &folder); QString getSavedCallsFolder () const; void setSavedCallsFolder (const QString &folder); QString getDownloadFolder () const; void setDownloadFolder (const QString &folder); QString getRemoteProvisioning () const; void setRemoteProvisioning (const QString &remoteProvisioning); bool getExitOnClose () const; void setExitOnClose (bool value); // --------------------------------------------------------------------------- QString getLogsFolder () const; void setLogsFolder (const QString &folder); QString getLogsUploadUrl () const; void setLogsUploadUrl (const QString &url); bool getLogsEnabled () const; void setLogsEnabled (bool status); QString getLogsEmail () const; void setLogsEmail (const QString &email); // --------------------------------------------------------------------------- static QString getLogsFolder (const std::shared_ptr &config); static bool getLogsEnabled (const std::shared_ptr &config); // --------------------------------------------------------------------------- bool getDeveloperSettingsEnabled () const; void setDeveloperSettingsEnabled (bool status); void handleCallCreated(const std::shared_ptr &call); void handleCallStateChanged(const std::shared_ptr &call, linphone::Call::State state); bool getIsInCall() const; static const std::string UiSection; // =========================================================================== // SIGNALS. // =========================================================================== signals: // Assistant. ---------------------------------------------------------------- void createAppSipAccountEnabledChanged (bool status); void fetchRemoteConfigurationEnabledChanged (bool status); void useAppSipAccountEnabledChanged (bool status); void useOtherSipAccountEnabledChanged (bool status); void assistantSupportsPhoneNumbersChanged (bool status); // Audio. -------------------------------------------------------------------- void captureGraphRunningChanged(bool running); void playbackGainChanged(float gain); void captureGainChanged(float gain); void captureDevicesChanged (const QStringList &devices); void playbackDevicesChanged (const QStringList &devices); void captureDeviceChanged (const QString &device); void playbackDeviceChanged (const QString &device); void ringerDeviceChanged (const QString &device); void ringPathChanged (const QString &path); void echoCancellationEnabledChanged (bool status); void showAudioCodecsChanged (bool status); // Video. -------------------------------------------------------------------- void videoDevicesChanged (const QStringList &devices); void videoDeviceChanged (const QString &device); void videoPresetChanged (const QString &preset); void videoFramerateChanged (int framerate); void videoDefinitionChanged (const QVariantMap &definition); void showVideoCodecsChanged (bool status); // Chat & calls. ------------------------------------------------------------- void autoAnswerStatusChanged (bool status); void autoAnswerVideoStatusChanged (bool status); void autoAnswerDelayChanged (int delay); void showTelKeypadAutomaticallyChanged (bool status); void keepCallsWindowInBackgroundChanged (bool status); void outgoingCallsEnabledChanged (bool status); void callRecorderEnabledChanged (bool status); void automaticallyRecordCallsChanged (bool status); void callPauseEnabledChanged (bool status); void muteMicrophoneEnabledChanged (bool status); void chatEnabledChanged (bool status); void conferenceEnabledChanged (bool status); void chatNotificationSoundEnabledChanged (bool status); void chatNotificationSoundPathChanged (const QString &path); void fileTransferUrlChanged (const QString &url); void mediaEncryptionChanged (MediaEncryption encryption); void limeStateChanged (bool state); void contactsEnabledChanged (bool status); // Network. ------------------------------------------------------------------ void showNetworkSettingsChanged (bool status); void dtmfsProtocolChanged (); void ipv6EnabledChanged (bool status); void downloadBandWidthChanged (int bandwidth); void uploadBandWidthChanged (int bandwidth); bool adaptiveRateControlEnabledChanged (bool status); void tcpPortChanged (int port); void udpPortChanged (int port); void audioPortRangeChanged (int a, int b); void videoPortRangeChanged (int a, int b); void iceEnabledChanged (bool status); void turnEnabledChanged (bool status); void stunServerChanged (const QString &server); void turnUserChanged (const QString &user); void turnPasswordChanged (const QString &password); void dscpSipChanged (int dscp); void dscpAudioChanged (int dscp); void dscpVideoChanged (int dscp); void rlsUriEnabledChanged (bool status); // UI. ----------------------------------------------------------------------- void savedScreenshotsFolderChanged (const QString &folder); void savedCallsFolderChanged (const QString &folder); void downloadFolderChanged (const QString &folder); void remoteProvisioningChanged (const QString &remoteProvisioning); void remoteProvisioningNotChanged (const QString &remoteProvisioning); void exitOnCloseChanged (bool value); // Advanced. ----------------------------------------------------------------- void logsFolderChanged (const QString &folder); void logsUploadUrlChanged (const QString &url); void logsEnabledChanged (bool status); void logsEmailChanged (const QString &email); bool developerSettingsEnabledChanged (bool status); bool isInCallChanged(bool); private: int mCurrentSettingsTab = 0; MediastreamerUtils::SimpleCaptureGraph *mSimpleCaptureGraph = nullptr; std::shared_ptr mConfig; }; Q_DECLARE_METATYPE(std::shared_ptr); #endif // SETTINGS_MODEL_H_ linphone-desktop-4.2.5/linphone-app/src/components/sip-addresses/000077500000000000000000000000001376717241300251345ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/src/components/sip-addresses/SipAddressObserver.cpp000066400000000000000000000032471376717241300314170ustar00rootroot00000000000000/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "SipAddressObserver.hpp" // ============================================================================= SipAddressObserver::SipAddressObserver (const QString &peerAddress, const QString &localAddress) { mPeerAddress = peerAddress; mLocalAddress = localAddress; } void SipAddressObserver::setContact (ContactModel *contact) { if (contact == mContact) return; mContact = contact; emit contactChanged(contact); } void SipAddressObserver::setPresenceStatus (const Presence::PresenceStatus &presenceStatus) { if (presenceStatus == mPresenceStatus) return; mPresenceStatus = presenceStatus; emit presenceStatusChanged(presenceStatus); } void SipAddressObserver::setUnreadMessageCount (int unreadMessageCount) { if (unreadMessageCount == mUnreadMessageCount) return; mUnreadMessageCount = unreadMessageCount; emit unreadMessageCountChanged(unreadMessageCount); } linphone-desktop-4.2.5/linphone-app/src/components/sip-addresses/SipAddressObserver.hpp000066400000000000000000000054631376717241300314260ustar00rootroot00000000000000/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef SIP_ADDRESS_OBSERVER_H_ #define SIP_ADDRESS_OBSERVER_H_ #include "components/presence/Presence.hpp" // ============================================================================= class ContactModel; class SipAddressObserver : public QObject { friend class SipAddressesModel; Q_OBJECT; Q_PROPERTY(QString peerAddress READ getPeerAddress CONSTANT); Q_PROPERTY(QString localAddress READ getLocalAddress CONSTANT); Q_PROPERTY(ContactModel *contact READ getContact NOTIFY contactChanged); Q_PROPERTY(Presence::PresenceStatus presenceStatus READ getPresenceStatus NOTIFY presenceStatusChanged); Q_PROPERTY(int unreadMessageCount READ getUnreadMessageCount NOTIFY unreadMessageCountChanged); public: SipAddressObserver (const QString &peerAddress, const QString &localAddress); signals: void contactChanged (ContactModel *contact); void presenceStatusChanged (const Presence::PresenceStatus &presenceStatus); void unreadMessageCountChanged (int unreadMessageCount); private: QString getPeerAddress () const { return mPeerAddress; } QString getLocalAddress () const { return mLocalAddress; } // --------------------------------------------------------------------------- ContactModel *getContact () const { return mContact; } void setContact (ContactModel *contact); // --------------------------------------------------------------------------- Presence::PresenceStatus getPresenceStatus () const { return mPresenceStatus; } void setPresenceStatus (const Presence::PresenceStatus &presenceStatus); // --------------------------------------------------------------------------- int getUnreadMessageCount () const { return mUnreadMessageCount; } void setUnreadMessageCount (int unreadMessageCount); QString mPeerAddress; QString mLocalAddress; ContactModel *mContact = nullptr; Presence::PresenceStatus mPresenceStatus = Presence::PresenceStatus::Offline; int mUnreadMessageCount = 0; }; Q_DECLARE_METATYPE(SipAddressObserver *); #endif // SIP_ADDRESS_OBSERVER_H_ linphone-desktop-4.2.5/linphone-app/src/components/sip-addresses/SipAddressesModel.cpp000066400000000000000000000610121376717241300312120ustar00rootroot00000000000000/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include #include #include #include #include "components/call/CallModel.hpp" #include "components/chat/ChatModel.hpp" #include "components/contact/ContactModel.hpp" #include "components/contact/VcardModel.hpp" #include "components/contacts/ContactsListModel.hpp" #include "components/core/CoreHandlers.hpp" #include "components/core/CoreManager.hpp" #include "components/history/HistoryModel.hpp" #include "components/settings/AccountSettingsModel.hpp" #include "utils/LinphoneUtils.hpp" #include "utils/Utils.hpp" #include "SipAddressesModel.hpp" // ============================================================================= using namespace std; // ----------------------------------------------------------------------------- static inline QVariantMap buildVariantMap (const SipAddressesModel::SipAddressEntry &sipAddressEntry) { return QVariantMap{ { "sipAddress", sipAddressEntry.sipAddress }, { "contact", QVariant::fromValue(sipAddressEntry.contact) }, { "presenceStatus", sipAddressEntry.presenceStatus }, { "__localToConferenceEntry", QVariant::fromValue(&sipAddressEntry.localAddressToConferenceEntry) } }; } SipAddressesModel::SipAddressesModel (QObject *parent) : QAbstractListModel(parent) { initSipAddresses(); CoreManager *coreManager = CoreManager::getInstance(); mCoreHandlers = coreManager->getHandlers(); QObject::connect(coreManager, &CoreManager::chatModelCreated, this, &SipAddressesModel::handleChatModelCreated); QObject::connect(coreManager, &CoreManager::historyModelCreated, this, &SipAddressesModel::handleHistoryModelCreated); ContactsListModel *contacts = CoreManager::getInstance()->getContactsListModel(); QObject::connect(contacts, &ContactsListModel::contactAdded, this, &SipAddressesModel::handleContactAdded); QObject::connect(contacts, &ContactsListModel::contactRemoved, this, &SipAddressesModel::handleContactRemoved); QObject::connect(contacts, &ContactsListModel::sipAddressAdded, this, &SipAddressesModel::handleSipAddressAdded); QObject::connect(contacts, &ContactsListModel::sipAddressRemoved, this, &SipAddressesModel::handleSipAddressRemoved); CoreHandlers *coreHandlers = mCoreHandlers.get(); QObject::connect(coreHandlers, &CoreHandlers::messageReceived, this, &SipAddressesModel::handleMessageReceived); QObject::connect(coreHandlers, &CoreHandlers::callStateChanged, this, &SipAddressesModel::handleCallStateChanged); QObject::connect(coreHandlers, &CoreHandlers::presenceReceived, this, &SipAddressesModel::handlePresenceReceived); QObject::connect(coreHandlers, &CoreHandlers::isComposingChanged, this, &SipAddressesModel::handleIsComposingChanged); } // ----------------------------------------------------------------------------- void SipAddressesModel::reset(){ mPeerAddressToSipAddressEntry.clear(); mRefs.clear(); resetInternalData(); initSipAddresses(); emit sipAddressReset(); } int SipAddressesModel::rowCount (const QModelIndex &) const { return mRefs.count(); } QHash SipAddressesModel::roleNames () const { QHash roles; roles[Qt::DisplayRole] = "$sipAddress"; return roles; } QVariant SipAddressesModel::data (const QModelIndex &index, int role) const { int row = index.row(); if (!index.isValid() || row < 0 || row >= mRefs.count()) return QVariant(); if (role == Qt::DisplayRole) return buildVariantMap(*mRefs[row]); return QVariant(); } // ----------------------------------------------------------------------------- QVariantMap SipAddressesModel::find (const QString &sipAddress) const { auto it = mPeerAddressToSipAddressEntry.find(sipAddress); if (it == mPeerAddressToSipAddressEntry.end()) return QVariantMap(); return buildVariantMap(*it); } // ----------------------------------------------------------------------------- ContactModel *SipAddressesModel::mapSipAddressToContact (const QString &sipAddress) const { auto it = mPeerAddressToSipAddressEntry.find(sipAddress); return it == mPeerAddressToSipAddressEntry.end() ? nullptr : it->contact; } // ----------------------------------------------------------------------------- SipAddressObserver *SipAddressesModel::getSipAddressObserver (const QString &peerAddress, const QString &localAddress) { SipAddressObserver *model = new SipAddressObserver(peerAddress, localAddress); const QString cleanedPeerAddress = Utils::cleanSipAddress(peerAddress); const QString cleanedLocalAddress = Utils::cleanSipAddress(localAddress); auto it = mPeerAddressToSipAddressEntry.find(cleanedPeerAddress); if (it != mPeerAddressToSipAddressEntry.end()) { model->setContact(it->contact); model->setPresenceStatus(it->presenceStatus); auto it2 = it->localAddressToConferenceEntry.find(cleanedLocalAddress); if (it2 != it->localAddressToConferenceEntry.end()) model->setUnreadMessageCount(it2->unreadMessageCount+it2->missedCallCount); } mObservers.insert(cleanedPeerAddress, model); QObject::connect(model, &SipAddressObserver::destroyed, this, [this, model, cleanedPeerAddress, cleanedLocalAddress]() { // Do not use `model` methods. `model` is partially destroyed here! if (mObservers.remove(cleanedPeerAddress, model) == 0) qWarning() << QStringLiteral("Unable to remove (%1, %2) from observers.") .arg(cleanedPeerAddress).arg(cleanedLocalAddress); }); return model; } // ----------------------------------------------------------------------------- QString SipAddressesModel::getTransportFromSipAddress (const QString &sipAddress) { if( sipAddress.toUpper().contains("TRANSPORT=")) {// Transport has been specified : check for it const shared_ptr address = linphone::Factory::get()->createAddress( Utils::appStringToCoreString(sipAddress) ); if (!address) return QString("TLS"); // Return TLS by default switch (address->getTransport()) { case linphone::TransportType::Udp: return QStringLiteral("UDP"); case linphone::TransportType::Tcp: return QStringLiteral("TCP"); case linphone::TransportType::Tls: return QStringLiteral("TLS"); case linphone::TransportType::Dtls: return QStringLiteral("DTLS"); } } return QString("TLS"); } QString SipAddressesModel::addTransportToSipAddress (const QString &sipAddress, const QString &transport) { shared_ptr address = linphone::Factory::get()->createAddress( Utils::appStringToCoreString(sipAddress) ); if (!address) return QString(""); address->setTransport(LinphoneUtils::stringToTransportType(transport.toUpper())); return Utils::coreStringToAppString(address->asString()); } // ----------------------------------------------------------------------------- QString SipAddressesModel::interpretSipAddress (const QString &sipAddress, bool checkUsername) { shared_ptr lAddress = CoreManager::getInstance()->getCore()->interpretUrl( Utils::appStringToCoreString(sipAddress) ); if (lAddress && (!checkUsername || !lAddress->getUsername().empty())) return Utils::coreStringToAppString(lAddress->asStringUriOnly()); return QString(""); } QString SipAddressesModel::interpretSipAddress (const QUrl &sipAddress) { return sipAddress.toString(); } bool SipAddressesModel::addressIsValid (const QString &address) { return !!linphone::Factory::get()->createAddress( Utils::appStringToCoreString(address) ); } bool SipAddressesModel::sipAddressIsValid (const QString &sipAddress) { shared_ptr address = linphone::Factory::get()->createAddress( Utils::appStringToCoreString(sipAddress) ); return address && !address->getUsername().empty(); } // Return at most : sip:username@domain QString SipAddressesModel::cleanSipAddress (const QString &sipAddress) { return Utils::cleanSipAddress(sipAddress); } // ----------------------------------------------------------------------------- bool SipAddressesModel::removeRow (int row, const QModelIndex &parent) { return removeRows(row, 1, parent); } bool SipAddressesModel::removeRows (int row, int count, const QModelIndex &parent) { int limit = row + count - 1; if (row < 0 || count < 0 || limit >= mRefs.count()) return false; beginRemoveRows(parent, row, limit); for (int i = 0; i < count; ++i) mPeerAddressToSipAddressEntry.remove(mRefs.takeAt(row)->sipAddress); endRemoveRows(); return true; } // ----------------------------------------------------------------------------- void SipAddressesModel::handleChatModelCreated (const shared_ptr &chatModel) { ChatModel *ptr = chatModel.get(); QObject::connect(ptr, &ChatModel::allEntriesRemoved, this, [this, ptr] { handleAllEntriesRemoved(ptr); }); QObject::connect(ptr, &ChatModel::lastEntryRemoved, this, [this, ptr] { handleLastEntryRemoved(ptr); }); QObject::connect(ptr, &ChatModel::messageCountReset, this, [this, ptr] { handleMessageCountReset(ptr); }); QObject::connect(ptr, &ChatModel::messageSent, this, &SipAddressesModel::handleMessageSent); } void SipAddressesModel::handleHistoryModelCreated (HistoryModel *historyModel) { QObject::connect(historyModel, &HistoryModel::callCountReset, this, [this] { handleAllCallCountReset(); }); } void SipAddressesModel::handleContactAdded (ContactModel *contact) { for (const auto &sipAddress : contact->getVcardModel()->getSipAddresses()) addOrUpdateSipAddress(sipAddress.toString(), contact); } void SipAddressesModel::handleContactRemoved (const ContactModel *contact) { for (const auto &sipAddress : contact->getVcardModel()->getSipAddresses()) removeContactOfSipAddress(sipAddress.toString()); } void SipAddressesModel::handleSipAddressAdded (ContactModel *contact, const QString &sipAddress) { ContactModel *mappedContact = mapSipAddressToContact(sipAddress); if (mappedContact) { qWarning() << "Unable to map sip address" << sipAddress << "to" << contact << "- already used by" << mappedContact; return; } addOrUpdateSipAddress(sipAddress, contact); } void SipAddressesModel::handleSipAddressRemoved (ContactModel *contact, const QString &sipAddress) { ContactModel *mappedContact = mapSipAddressToContact(sipAddress); if (contact != mappedContact) { qWarning() << "Unable to remove sip address" << sipAddress << "of" << contact << "- already used by" << mappedContact; return; } removeContactOfSipAddress(sipAddress); } void SipAddressesModel::handleMessageReceived (const shared_ptr &message) { qInfo() << "Handle message received."; const QString peerAddress(Utils::coreStringToAppString(message->getChatRoom()->getPeerAddress()->asStringUriOnly())); addOrUpdateSipAddress(peerAddress, message); } void SipAddressesModel::handleCallStateChanged ( const shared_ptr &call, linphone::Call::State state ) { if (state == linphone::Call::State::End || state == linphone::Call::State::Error) addOrUpdateSipAddress( Utils::coreStringToAppString(call->getRemoteAddress()->asStringUriOnly()), call ); } void SipAddressesModel::handlePresenceReceived ( const QString &sipAddress, const shared_ptr &presenceModel ) { Presence::PresenceStatus status; switch (presenceModel->getConsolidatedPresence()) { case linphone::ConsolidatedPresence::Online: status = Presence::PresenceStatus::Online; break; case linphone::ConsolidatedPresence::Busy: status = Presence::PresenceStatus::Busy; break; case linphone::ConsolidatedPresence::DoNotDisturb: status = Presence::PresenceStatus::DoNotDisturb; break; case linphone::ConsolidatedPresence::Offline: status = Presence::PresenceStatus::Offline; break; } auto it = mPeerAddressToSipAddressEntry.find(sipAddress); if (it != mPeerAddressToSipAddressEntry.end()) { qInfo() << QStringLiteral("Update presence of `%1`: %2.").arg(sipAddress).arg(status); it->presenceStatus = status; int row = mRefs.indexOf(&(*it)); Q_ASSERT(row != -1); emit dataChanged(index(row, 0), index(row, 0)); } updateObservers(sipAddress, status); } void SipAddressesModel::handleAllEntriesRemoved (ChatModel *chatModel) { auto it = mPeerAddressToSipAddressEntry.find(chatModel->getPeerAddress()); if (it == mPeerAddressToSipAddressEntry.end()) return; auto it2 = it->localAddressToConferenceEntry.find(Utils::cleanSipAddress(chatModel->getLocalAddress())); if (it2 == it->localAddressToConferenceEntry.end()) return; it->localAddressToConferenceEntry.erase(it2); int row = mRefs.indexOf(&(*it)); Q_ASSERT(row != -1); // No history, no contact => Remove sip address from list. if (!it->contact && it->localAddressToConferenceEntry.empty()) { removeRow(row); return; } emit dataChanged(index(row, 0), index(row, 0)); } void SipAddressesModel::handleLastEntryRemoved (ChatModel *chatModel) { auto it = mPeerAddressToSipAddressEntry.find(chatModel->getPeerAddress()); if (it == mPeerAddressToSipAddressEntry.end()) return; auto it2 = it->localAddressToConferenceEntry.find(Utils::cleanSipAddress(chatModel->getLocalAddress())); if (it2 == it->localAddressToConferenceEntry.end()) return; int row = mRefs.indexOf(&(*it)); Q_ASSERT(row != -1); Q_ASSERT(chatModel->rowCount() > 0); const QVariantMap map = chatModel->data( chatModel->index(chatModel->rowCount() - 1, 0), ChatModel::ChatEntry ).toMap(); // Update the timestamp with the new last chat message timestamp. it2->timestamp = map["timestamp"].toDateTime(); emit dataChanged(index(row, 0), index(row, 0)); } void SipAddressesModel::handleAllCallCountReset () { for( auto peer = mPeerAddressToSipAddressEntry.begin() ; peer != mPeerAddressToSipAddressEntry.end() ; ++peer){ for( auto local = peer->localAddressToConferenceEntry.begin() ; local != peer->localAddressToConferenceEntry.end() ; ++local){ local->missedCallCount = 0; updateObservers(peer.key(), local.key(), local->unreadMessageCount, local->missedCallCount); } int row = mRefs.indexOf(&(*peer)); emit dataChanged(index(row, 0), index(row, 0)); } } void SipAddressesModel::handleMessageCountReset (ChatModel *chatModel) { const QString &peerAddress = Utils::cleanSipAddress(chatModel->getPeerAddress()); auto it = mPeerAddressToSipAddressEntry.find(peerAddress); if (it == mPeerAddressToSipAddressEntry.end()) return; const QString &localAddress = Utils::cleanSipAddress(chatModel->getLocalAddress()); auto it2 = it->localAddressToConferenceEntry.find(localAddress); if (it2 == it->localAddressToConferenceEntry.end()) return; it2->unreadMessageCount = 0; it2->missedCallCount = 0; int row = mRefs.indexOf(&(*it)); Q_ASSERT(row != -1); emit dataChanged(index(row, 0), index(row, 0)); updateObservers(peerAddress, localAddress, 0, 0); } void SipAddressesModel::handleMessageSent (const shared_ptr &message) { qInfo() << "Handle message sent."; const QString peerAddress(Utils::coreStringToAppString(message->getChatRoom()->getPeerAddress()->asStringUriOnly())); addOrUpdateSipAddress(peerAddress, message); } void SipAddressesModel::handleIsComposingChanged (const shared_ptr &chatRoom) { auto it = mPeerAddressToSipAddressEntry.find(Utils::cleanSipAddress(Utils::coreStringToAppString(chatRoom->getPeerAddress()->asStringUriOnly()))); if (it == mPeerAddressToSipAddressEntry.end()) return; auto it2 = it->localAddressToConferenceEntry.find( Utils::cleanSipAddress(Utils::coreStringToAppString(chatRoom->getLocalAddress()->asStringUriOnly())) ); if (it2 == it->localAddressToConferenceEntry.end()) return; it2->isComposing = chatRoom->isRemoteComposing(); int row = mRefs.indexOf(&(*it)); Q_ASSERT(row != -1); emit dataChanged(index(row, 0), index(row, 0)); } // ----------------------------------------------------------------------------- void SipAddressesModel::addOrUpdateSipAddress (SipAddressEntry &sipAddressEntry, ContactModel *contact) { const QString &sipAddress = sipAddressEntry.sipAddress; sipAddressEntry.contact = contact; if (!sipAddressEntry.contact) qWarning() << QStringLiteral("`contact` field is empty on sip address: `%1`.").arg(sipAddress); updateObservers(sipAddress, contact); } void SipAddressesModel::addOrUpdateSipAddress (SipAddressEntry &sipAddressEntry, const shared_ptr &call) { const shared_ptr callLog = call->getCallLog(); QString localAddress(Utils::cleanSipAddress(Utils::coreStringToAppString(callLog->getLocalAddress()->asStringUriOnly()))); QString peerAddress(Utils::cleanSipAddress(Utils::coreStringToAppString(callLog->getRemoteAddress()->asStringUriOnly()))); ConferenceEntry &conferenceEntry = sipAddressEntry.localAddressToConferenceEntry[ localAddress ]; qInfo() << QStringLiteral("Update (`%1`, `%2`) from chat call.").arg(sipAddressEntry.sipAddress, localAddress); conferenceEntry.timestamp = callLog->getStatus() == linphone::Call::Status::Success ? QDateTime::fromMSecsSinceEpoch((callLog->getStartDate() + callLog->getDuration()) * 1000) : QDateTime::fromMSecsSinceEpoch(callLog->getStartDate() * 1000); conferenceEntry.missedCallCount = CoreManager::getInstance()->getMissedCallCount(peerAddress, localAddress); updateObservers(sipAddressEntry.sipAddress, localAddress, conferenceEntry.unreadMessageCount,conferenceEntry.missedCallCount); } void SipAddressesModel::addOrUpdateSipAddress (SipAddressEntry &sipAddressEntry, const shared_ptr &message) { shared_ptr chatRoom(message->getChatRoom()); int count = chatRoom->getUnreadMessagesCount(); QString localAddress(Utils::cleanSipAddress(Utils::coreStringToAppString(chatRoom->getLocalAddress()->asStringUriOnly()))); QString peerAddress(Utils::cleanSipAddress(Utils::coreStringToAppString(chatRoom->getPeerAddress()->asStringUriOnly()))); qInfo() << QStringLiteral("Update (`%1`, `%2`) from chat message.").arg(sipAddressEntry.sipAddress, localAddress); ConferenceEntry &conferenceEntry = sipAddressEntry.localAddressToConferenceEntry[localAddress]; conferenceEntry.timestamp = QDateTime::fromMSecsSinceEpoch(message->getTime() * 1000); conferenceEntry.unreadMessageCount = count ; conferenceEntry.missedCallCount = CoreManager::getInstance()->getMissedCallCount(peerAddress, localAddress); updateObservers(sipAddressEntry.sipAddress, localAddress, count,conferenceEntry.missedCallCount); } template void SipAddressesModel::addOrUpdateSipAddress (const QString &sipAddress, T data) { auto it = mPeerAddressToSipAddressEntry.find(sipAddress); if (it != mPeerAddressToSipAddressEntry.end()) { addOrUpdateSipAddress(*it, data); int row = mRefs.indexOf(&(*it)); Q_ASSERT(row != -1); emit dataChanged(index(row, 0), index(row, 0)); return; } SipAddressEntry sipAddressEntry{ sipAddress, nullptr, Presence::Offline, {} }; addOrUpdateSipAddress(sipAddressEntry, data); int row = mRefs.count(); beginInsertRows(QModelIndex(), row, row); mPeerAddressToSipAddressEntry[sipAddress] = move(sipAddressEntry); mRefs << &mPeerAddressToSipAddressEntry[sipAddress]; endInsertRows(); } // ----------------------------------------------------------------------------- void SipAddressesModel::removeContactOfSipAddress (const QString &sipAddress) { auto it = mPeerAddressToSipAddressEntry.find(sipAddress); if (it == mPeerAddressToSipAddressEntry.end()) { qWarning() << QStringLiteral("Unable to remove unavailable sip address: `%1`.").arg(sipAddress); return; } // Try to map other contact on this sip address. ContactModel *contactModel = CoreManager::getInstance()->getContactsListModel()->findContactModelFromSipAddress(sipAddress); updateObservers(sipAddress, contactModel); qInfo() << QStringLiteral("Map new contact on sip address: `%1`.").arg(sipAddress) << contactModel; addOrUpdateSipAddress(*it, contactModel); int row = mRefs.indexOf(&(*it)); Q_ASSERT(row != -1); // History or contact exists, signal changes. if (!it->localAddressToConferenceEntry.empty() || contactModel) { emit dataChanged(index(row, 0), index(row, 0)); return; } // Remove sip address if no history. removeRow(row); } // ----------------------------------------------------------------------------- void SipAddressesModel::initSipAddresses () { QElapsedTimer timer; timer.start(); initSipAddressesFromChat(); initSipAddressesFromCalls(); initRefs(); initSipAddressesFromContacts(); qInfo() << "Sip addresses model initialized in:" << timer.elapsed() << "ms."; } void SipAddressesModel::initSipAddressesFromChat () { for (const auto &chatRoom : CoreManager::getInstance()->getCore()->getChatRooms()) { list> history(chatRoom->getHistory(1)); if (history.empty()) continue; QString peerAddress(Utils::cleanSipAddress(Utils::coreStringToAppString(chatRoom->getPeerAddress()->asStringUriOnly()))); QString localAddress(Utils::cleanSipAddress(Utils::coreStringToAppString(chatRoom->getLocalAddress()->asStringUriOnly()))); getSipAddressEntry(peerAddress)->localAddressToConferenceEntry[localAddress] = { chatRoom->getUnreadMessagesCount(), CoreManager::getInstance()->getMissedCallCount(peerAddress, localAddress), false, QDateTime::fromMSecsSinceEpoch(history.back()->getTime() * 1000) }; } } void SipAddressesModel::initSipAddressesFromCalls () { using ConferenceId = QPair; QSet conferenceDone; for (const auto &callLog : CoreManager::getInstance()->getCore()->getCallLogs()) { const QString peerAddress(Utils::cleanSipAddress(Utils::coreStringToAppString(callLog->getRemoteAddress()->asStringUriOnly()))); const QString localAddress(Utils::cleanSipAddress(Utils::coreStringToAppString(callLog->getLocalAddress()->asStringUriOnly()))); ConferenceId conferenceId{ peerAddress, localAddress }; if (conferenceDone.contains(conferenceId)) continue; // Already used. conferenceDone << conferenceId; // The duration can be wrong if status is not success. QDateTime timestamp(callLog->getStatus() == linphone::Call::Status::Success ? QDateTime::fromMSecsSinceEpoch((callLog->getStartDate() + callLog->getDuration()) * 1000) : QDateTime::fromMSecsSinceEpoch(callLog->getStartDate() * 1000)); auto &localToConferenceEntry = getSipAddressEntry(peerAddress)->localAddressToConferenceEntry; auto it = localToConferenceEntry.find(localAddress); if (it == localToConferenceEntry.end()) localToConferenceEntry[localAddress] = { 0,0, false, move(timestamp) }; else if (it->timestamp.isNull() || timestamp > it->timestamp) it->timestamp = move(timestamp); } } void SipAddressesModel::initSipAddressesFromContacts () { for (auto &contact : CoreManager::getInstance()->getContactsListModel()->mList) handleContactAdded(contact); } void SipAddressesModel::initRefs () { for (const auto &sipAddressEntry : mPeerAddressToSipAddressEntry) mRefs << &sipAddressEntry; } // ----------------------------------------------------------------------------- void SipAddressesModel::updateObservers (const QString &sipAddress, ContactModel *contact) { for (auto &observer : mObservers.values(sipAddress)) observer->setContact(contact); } void SipAddressesModel::updateObservers (const QString &sipAddress, const Presence::PresenceStatus &presenceStatus) { for (auto &observer : mObservers.values(sipAddress)) observer->setPresenceStatus(presenceStatus); } void SipAddressesModel::updateObservers (const QString &peerAddress, const QString &localAddress, int messageCount, int missedCallCount) { for (auto &observer : mObservers.values(peerAddress)) { if (observer->getLocalAddress() == localAddress) { observer->setUnreadMessageCount(messageCount+missedCallCount); return; } } } linphone-desktop-4.2.5/linphone-app/src/components/sip-addresses/SipAddressesModel.hpp000066400000000000000000000144421376717241300312240ustar00rootroot00000000000000/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef SIP_ADDRESSES_MODEL_H_ #define SIP_ADDRESSES_MODEL_H_ #include #include #include "SipAddressObserver.hpp" // ============================================================================= class QUrl; class ChatModel; class CoreHandlers; class HistoryModel; class SipAddressesModel : public QAbstractListModel { Q_OBJECT; public: struct ConferenceEntry { int unreadMessageCount; int missedCallCount; bool isComposing; QDateTime timestamp; }; struct SipAddressEntry { QString sipAddress; ContactModel *contact; Presence::PresenceStatus presenceStatus; QHash localAddressToConferenceEntry; }; SipAddressesModel (QObject *parent = Q_NULLPTR); void reset(); int rowCount (const QModelIndex &index = QModelIndex()) const override; QHash roleNames () const override; QVariant data (const QModelIndex &index, int role = Qt::DisplayRole) const override; Q_INVOKABLE QVariantMap find (const QString &sipAddress) const; Q_INVOKABLE ContactModel *mapSipAddressToContact (const QString &sipAddress) const; Q_INVOKABLE SipAddressObserver *getSipAddressObserver (const QString &peerAddress, const QString &localAddress); // --------------------------------------------------------------------------- // Sip addresses helpers. // --------------------------------------------------------------------------- Q_INVOKABLE static QString getTransportFromSipAddress (const QString &sipAddress); Q_INVOKABLE static QString addTransportToSipAddress (const QString &sipAddress, const QString &transport); Q_INVOKABLE static QString interpretSipAddress (const QString &sipAddress, bool checkUsername = true); Q_INVOKABLE static QString interpretSipAddress (const QUrl &sipAddress); Q_INVOKABLE static bool addressIsValid (const QString &address); Q_INVOKABLE static bool sipAddressIsValid (const QString &sipAddress); Q_INVOKABLE static QString cleanSipAddress (const QString &sipAddress); // --------------------------------------------------------------------------- signals: void sipAddressReset();// The model has been reset public slots: void handleAllCallCountReset (); private: bool removeRow (int row, const QModelIndex &parent = QModelIndex()); bool removeRows (int row, int count, const QModelIndex &parent = QModelIndex()) override; // --------------------------------------------------------------------------- void handleChatModelCreated (const std::shared_ptr &chatModel); void handleHistoryModelCreated (HistoryModel *historyModel) ; void handleContactAdded (ContactModel *contact); void handleContactRemoved (const ContactModel *contact); void handleSipAddressAdded (ContactModel *contact, const QString &sipAddress); void handleSipAddressRemoved (ContactModel *contact, const QString &sipAddress); void handleMessageReceived (const std::shared_ptr &message); void handleCallStateChanged (const std::shared_ptr &call, linphone::Call::State state); void handlePresenceReceived (const QString &sipAddress, const std::shared_ptr &presenceModel); void handleAllEntriesRemoved (ChatModel *chatModel); void handleLastEntryRemoved (ChatModel *chatModel); void handleMessageCountReset (ChatModel *chatModel); void handleMessageSent (const std::shared_ptr &message); void handleIsComposingChanged (const std::shared_ptr &chatRoom); // --------------------------------------------------------------------------- // A sip address exists in this list if a contact is linked to it, or a call, or a message. void addOrUpdateSipAddress (SipAddressEntry &sipAddressEntry, ContactModel *contact); void addOrUpdateSipAddress (SipAddressEntry &sipAddressEntry, const std::shared_ptr &call); void addOrUpdateSipAddress (SipAddressEntry &sipAddressEntry, const std::shared_ptr &message); //NMN TODO bind to missedCall event and implement void addOrUpdateSipAddress template void addOrUpdateSipAddress (const QString &sipAddress, T data); // --------------------------------------------------------------------------- void removeContactOfSipAddress (const QString &sipAddress); void initSipAddresses (); void initSipAddressesFromChat (); void initSipAddressesFromCalls (); void initSipAddressesFromContacts (); void initRefs (); void updateObservers (const QString &sipAddress, ContactModel *contact); void updateObservers (const QString &sipAddress, const Presence::PresenceStatus &presenceStatus); void updateObservers (const QString &peerAddress, const QString &localAddress, int messageCount, int missedCallCount); // --------------------------------------------------------------------------- SipAddressEntry *getSipAddressEntry (const QString &peerAddress) { auto it = mPeerAddressToSipAddressEntry.find(peerAddress); if (it == mPeerAddressToSipAddressEntry.end()) it = mPeerAddressToSipAddressEntry.insert(peerAddress, { peerAddress, nullptr, Presence::Offline, {} }); return &(*it); } QHash mPeerAddressToSipAddressEntry; QList mRefs; QMultiHash mObservers; std::shared_ptr mCoreHandlers; }; using LocalAddressToConferenceEntry = QHash; Q_DECLARE_METATYPE(const LocalAddressToConferenceEntry *); #endif // SIP_ADDRESSES_MODEL_H_ linphone-desktop-4.2.5/linphone-app/src/components/sip-addresses/SipAddressesProxyModel.cpp000066400000000000000000000104221376717241300322530ustar00rootroot00000000000000/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "components/contact/ContactModel.hpp" #include "components/contact/VcardModel.hpp" #include "components/core/CoreManager.hpp" #include "SipAddressesModel.hpp" #include "SipAddressesProxyModel.hpp" // ============================================================================= namespace { constexpr int WeightPos0 = 5; constexpr int WeightPos1 = 4; constexpr int WeightPos2 = 3; constexpr int WeightPos3 = 2; constexpr int WeightPosOther = 1; } const QRegExp SipAddressesProxyModel::SearchSeparators("^[^_.-;@ ][_.-;@ ]"); // ----------------------------------------------------------------------------- SipAddressesProxyModel::SipAddressesProxyModel (QObject *parent) : QSortFilterProxyModel(parent) { setSourceModel(CoreManager::getInstance()->getSipAddressesModel()); sort(0); } // ----------------------------------------------------------------------------- void SipAddressesProxyModel::setFilter (const QString &pattern) { mFilter = pattern; invalidate(); } // ----------------------------------------------------------------------------- bool SipAddressesProxyModel::filterAcceptsRow (int sourceRow, const QModelIndex &sourceParent) const { const QModelIndex index = sourceModel()->index(sourceRow, 0, sourceParent); return computeEntryWeight(index.data().toMap()) > 0; } bool SipAddressesProxyModel::lessThan (const QModelIndex &left, const QModelIndex &right) const { const QVariantMap mapA = sourceModel()->data(left).toMap(); const QVariantMap mapB = sourceModel()->data(right).toMap(); const QString sipAddressA = mapA["sipAddress"].toString(); const QString sipAddressB = mapB["sipAddress"].toString(); // TODO: Use a cache, do not compute the same value as `filterAcceptsRow`. int weightA = computeEntryWeight(mapA); int weightB = computeEntryWeight(mapB); // 1. Not the same weight. if (weightA != weightB) return weightA > weightB; const ContactModel *contactA = mapA.value("contact").value(); const ContactModel *contactB = mapB.value("contact").value(); // 2. No contacts. if (!contactA && !contactB) return sipAddressA <= sipAddressB; // 3. No contact for a or b. if (!contactA || !contactB) return !!contactA; // 4. Same contact (address). if (contactA == contactB) return sipAddressA <= sipAddressB; // 5. Not the same contact name. int diff = contactA->mLinphoneFriend->getName().compare(contactB->mLinphoneFriend->getName()); if (diff) return diff <= 0; // 6. Same contact name, so compare sip addresses. return sipAddressA <= sipAddressB; } int SipAddressesProxyModel::computeEntryWeight (const QVariantMap &entry) const { int weight = computeStringWeight(entry["sipAddress"].toString().mid(4)); const ContactModel *contact = entry.value("contact").value(); if (contact) weight += computeStringWeight(contact->getVcardModel()->getUsername()); return weight; } int SipAddressesProxyModel::computeStringWeight (const QString &string) const { int index = -1; int offset = -1; while ((index = string.indexOf(mFilter, index + 1, Qt::CaseInsensitive)) != -1) { int tmpOffset = index - string.lastIndexOf(SearchSeparators, index) - 1; if ((tmpOffset != -1 && tmpOffset < offset) || offset == -1) if ((offset = tmpOffset) == 0) break; } switch (offset) { case -1: return 0; case 0: return WeightPos0; case 1: return WeightPos1; case 2: return WeightPos2; case 3: return WeightPos3; default: break; } return WeightPosOther; } linphone-desktop-4.2.5/linphone-app/src/components/sip-addresses/SipAddressesProxyModel.hpp000066400000000000000000000030741376717241300322650ustar00rootroot00000000000000/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef SIP_ADDRESSES_PROXY_MODEL_H_ #define SIP_ADDRESSES_PROXY_MODEL_H_ #include // ============================================================================= class SipAddressesProxyModel : public QSortFilterProxyModel { Q_OBJECT; public: SipAddressesProxyModel (QObject *parent = Q_NULLPTR); Q_INVOKABLE void setFilter (const QString &pattern); protected: bool filterAcceptsRow (int sourceRow, const QModelIndex &sourceParent) const override; bool lessThan (const QModelIndex &left, const QModelIndex &right) const override; private: int computeEntryWeight (const QVariantMap &entry) const; int computeStringWeight (const QString &string) const; QString mFilter; static const QRegExp SearchSeparators; }; #endif // SIP_ADDRESSES_PROXY_MODEL_H_ linphone-desktop-4.2.5/linphone-app/src/components/sound-player/000077500000000000000000000000001376717241300250105ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/src/components/sound-player/SoundPlayer.cpp000066400000000000000000000143211376717241300277620ustar00rootroot00000000000000/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include #include #include "components/core/CoreManager.hpp" #include "components/settings/SettingsModel.hpp" #include "utils/Utils.hpp" #include "SoundPlayer.hpp" // ============================================================================= using namespace std; namespace { int ForceCloseTimerInterval = 20; } class SoundPlayer::Handlers : public linphone::PlayerListener { public: Handlers (SoundPlayer *soundPlayer) { mSoundPlayer = soundPlayer; } private: void onEofReached (const shared_ptr &) override { QMutex &mutex = mSoundPlayer->mForceCloseMutex; // Workaround. // This callback is called in a standard thread of mediastreamer, not a QThread. // Signals, connect functions, timers... are unavailable. mutex.lock(); mSoundPlayer->mForceClose = true; mutex.unlock(); } SoundPlayer *mSoundPlayer; }; // ----------------------------------------------------------------------------- SoundPlayer::SoundPlayer (QObject *parent) : QObject(parent) { CoreManager *coreManager = CoreManager::getInstance(); SettingsModel *settingsModel = coreManager->getSettingsModel(); mForceCloseTimer = new QTimer(this); mForceCloseTimer->setInterval(ForceCloseTimerInterval); QObject::connect(mForceCloseTimer, &QTimer::timeout, this, &SoundPlayer::handleEof); mHandlers = make_shared(this); // Connection to rebuilding player when changing ringer selection. This player is only for Ringer. QObject::connect(settingsModel, &SettingsModel::ringerDeviceChanged, this, [this] { rebuildInternalPlayer(); }); buildInternalPlayer(); } SoundPlayer::~SoundPlayer () { mForceCloseTimer->stop(); if( mInternalPlayer) mInternalPlayer->close(); } // ----------------------------------------------------------------------------- void SoundPlayer::pause () { if (mPlaybackState == SoundPlayer::PausedState) return; if (mInternalPlayer->pause()) { setError(QStringLiteral("Unable to pause: `%1`").arg(mSource)); return; } mForceCloseTimer->stop(); mPlaybackState = SoundPlayer::PausedState; emit paused(); emit playbackStateChanged(mPlaybackState); } void SoundPlayer::play () { if (mPlaybackState == SoundPlayer::PlayingState) return; if ( (mPlaybackState == SoundPlayer::StoppedState || mPlaybackState == SoundPlayer::ErrorState) && mInternalPlayer->open(Utils::appStringToCoreString(mSource)) ) { qWarning() << QStringLiteral("Unable to open: `%1`").arg(mSource); return; } if (mInternalPlayer->start() ) { setError(QStringLiteral("Unable to play: `%1`").arg(mSource)); return; } mForceCloseTimer->start(); mPlaybackState = SoundPlayer::PlayingState; emit playing(); emit playbackStateChanged(mPlaybackState); } void SoundPlayer::stop () { stop(false); } // ----------------------------------------------------------------------------- void SoundPlayer::seek (int offset) { mInternalPlayer->seek(offset); } // ----------------------------------------------------------------------------- int SoundPlayer::getPosition () const { return mInternalPlayer->getCurrentPosition(); } // ----------------------------------------------------------------------------- void SoundPlayer::buildInternalPlayer () { CoreManager *coreManager = CoreManager::getInstance(); SettingsModel *settingsModel = coreManager->getSettingsModel(); mInternalPlayer = coreManager->getCore()->createLocalPlayer( Utils::appStringToCoreString(settingsModel->getRingerDevice()), "", nullptr ); if(mInternalPlayer) mInternalPlayer->addListener(mHandlers); } void SoundPlayer::rebuildInternalPlayer () { stop(true); buildInternalPlayer(); } void SoundPlayer::stop (bool force) { if (mPlaybackState == SoundPlayer::StoppedState && !force) return; mForceCloseTimer->stop(); mPlaybackState = SoundPlayer::StoppedState; if(mInternalPlayer) mInternalPlayer->close(); emit stopped(); emit playbackStateChanged(mPlaybackState); } // ----------------------------------------------------------------------------- void SoundPlayer::handleEof () { mForceCloseMutex.lock(); if (mForceClose) { mForceClose = false; stop(); } mForceCloseMutex.unlock(); } // ----------------------------------------------------------------------------- void SoundPlayer::setError (const QString &message) { qWarning() << message; mInternalPlayer->close(); if (mPlaybackState != SoundPlayer::ErrorState) { mPlaybackState = SoundPlayer::ErrorState; emit playbackStateChanged(mPlaybackState); } } // ----------------------------------------------------------------------------- QString SoundPlayer::getSource () const { return mSource; } void SoundPlayer::setSource (const QString &source) { if (source == mSource) return; stop(); mSource = source; emit sourceChanged(source); } // ----------------------------------------------------------------------------- SoundPlayer::PlaybackState SoundPlayer::getPlaybackState () const { return mPlaybackState; } void SoundPlayer::setPlaybackState (PlaybackState playbackState) { switch (playbackState) { case PlayingState: play(); break; case PausedState: pause(); break; case StoppedState: stop(); break; case ErrorState: break; } } // ----------------------------------------------------------------------------- int SoundPlayer::getDuration () const { return mInternalPlayer->getDuration(); } linphone-desktop-4.2.5/linphone-app/src/components/sound-player/SoundPlayer.hpp000066400000000000000000000047741376717241300300020ustar00rootroot00000000000000/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef SOUND_PLAYER_H_ #define SOUND_PLAYER_H_ #include #include #include // ============================================================================= class QTimer; namespace linphone { class Player; } class SoundPlayer : public QObject { class Handlers; Q_OBJECT; Q_PROPERTY(QString source READ getSource WRITE setSource NOTIFY sourceChanged); Q_PROPERTY(PlaybackState playbackState READ getPlaybackState WRITE setPlaybackState NOTIFY playbackStateChanged); Q_PROPERTY(int duration READ getDuration NOTIFY sourceChanged); public: enum PlaybackState { PlayingState, PausedState, StoppedState, ErrorState }; Q_ENUM(PlaybackState); SoundPlayer (QObject *parent = Q_NULLPTR); ~SoundPlayer (); Q_INVOKABLE void pause (); Q_INVOKABLE void play (); Q_INVOKABLE void stop (); Q_INVOKABLE void seek (int offset); Q_INVOKABLE int getPosition () const; signals: void sourceChanged (const QString &source); void paused (); void playing (); void stopped (); void playbackStateChanged (PlaybackState playbackState); private: void buildInternalPlayer (); void rebuildInternalPlayer (); void stop (bool force); void handleEof (); void setError (const QString &message); QString getSource () const; void setSource (const QString &source); PlaybackState getPlaybackState () const; void setPlaybackState (PlaybackState playbackState); int getDuration () const; QString mSource; PlaybackState mPlaybackState = StoppedState; bool mForceClose = false; QMutex mForceCloseMutex; QTimer *mForceCloseTimer = nullptr; std::shared_ptr mInternalPlayer; std::shared_ptr mHandlers; }; #endif // SOUND_PLAYER_H_ linphone-desktop-4.2.5/linphone-app/src/components/telephone-numbers/000077500000000000000000000000001376717241300260225ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/src/components/telephone-numbers/TelephoneNumbersModel.cpp000066400000000000000000000227031376717241300327720ustar00rootroot00000000000000/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "TelephoneNumbersModel.hpp" #include "utils/Utils.hpp" // ============================================================================= using namespace std; const QList> TelephoneNumbersModel::mCountryCodes = { { QLocale::Afghanistan, "93" }, { QLocale::Albania, "355" }, { QLocale::Algeria, "213" }, { QLocale::AmericanSamoa, "1" }, { QLocale::Andorra, "376" }, { QLocale::Angola, "244" }, { QLocale::Anguilla, "1" }, { QLocale::AntiguaAndBarbuda, "1" }, { QLocale::Argentina, "54" }, { QLocale::Armenia, "374" }, { QLocale::Aruba, "297" }, { QLocale::Australia, "61" }, { QLocale::Austria, "43" }, { QLocale::Azerbaijan, "994" }, { QLocale::Bahamas, "1" }, { QLocale::Bahrain, "973" }, { QLocale::Bangladesh, "880" }, { QLocale::Barbados, "1" }, { QLocale::Belarus, "375" }, { QLocale::Belgium, "32" }, { QLocale::Belize, "501" }, { QLocale::Benin, "229" }, { QLocale::Bermuda, "1" }, { QLocale::Bhutan, "975" }, { QLocale::Bolivia, "591" }, { QLocale::BosniaAndHerzegowina, "387" }, { QLocale::Botswana, "267" }, { QLocale::Brazil, "55" }, { QLocale::Brunei, "673" }, { QLocale::Bulgaria, "359" }, { QLocale::BurkinaFaso, "226" }, { QLocale::Burundi, "257" }, { QLocale::Cambodia, "855" }, { QLocale::Cameroon, "237" }, { QLocale::Canada, "1" }, { QLocale::CapeVerde, "238" }, { QLocale::CaymanIslands, "1" }, { QLocale::CentralAfricanRepublic, "236" }, { QLocale::Chad, "235" }, { QLocale::Chile, "56" }, { QLocale::China, "86" }, { QLocale::Colombia, "57" }, { QLocale::Comoros, "269" }, { QLocale::PeoplesRepublicOfCongo, "242" }, { QLocale::DemocraticRepublicOfCongo, "243" }, { QLocale::CookIslands, "682" }, { QLocale::CostaRica, "506" }, { QLocale::IvoryCoast, "225" }, { QLocale::Croatia, "385" }, { QLocale::Cuba, "53" }, { QLocale::Cyprus, "357" }, { QLocale::CzechRepublic, "420" }, { QLocale::Denmark, "45" }, { QLocale::Djibouti, "253" }, { QLocale::Dominica, "1" }, { QLocale::DominicanRepublic, "1" }, { QLocale::Ecuador, "593" }, { QLocale::Egypt, "20" }, { QLocale::ElSalvador, "503" }, { QLocale::EquatorialGuinea, "240" }, { QLocale::Eritrea, "291" }, { QLocale::Estonia, "372" }, { QLocale::Ethiopia, "251" }, { QLocale::FalklandIslands, "500" }, { QLocale::FaroeIslands, "298" }, { QLocale::Fiji, "679" }, { QLocale::Finland, "358" }, { QLocale::France, "33" }, { QLocale::FrenchGuiana, "594" }, { QLocale::FrenchPolynesia, "689" }, { QLocale::Gabon, "241" }, { QLocale::Gambia, "220" }, { QLocale::Georgia, "995" }, { QLocale::Germany, "49" }, { QLocale::Ghana, "233" }, { QLocale::Gibraltar, "350" }, { QLocale::Greece, "30" }, { QLocale::Greenland, "299" }, { QLocale::Grenada, "1" }, { QLocale::Guadeloupe, "590" }, { QLocale::Guam, "1" }, { QLocale::Guatemala, "502" }, { QLocale::Guinea, "224" }, { QLocale::GuineaBissau, "245" }, { QLocale::Guyana, "592" }, { QLocale::Haiti, "509" }, { QLocale::Honduras, "504" }, { QLocale::HongKong, "852" }, { QLocale::Hungary, "36" }, { QLocale::Iceland, "354" }, { QLocale::India, "91" }, { QLocale::Indonesia, "62" }, { QLocale::Iran, "98" }, { QLocale::Iraq, "964" }, { QLocale::Ireland, "353" }, { QLocale::Israel, "972" }, { QLocale::Italy, "39" }, { QLocale::Jamaica, "1" }, { QLocale::Japan, "81" }, { QLocale::Jordan, "962" }, { QLocale::Kazakhstan, "7" }, { QLocale::Kenya, "254" }, { QLocale::Kiribati, "686" }, { QLocale::DemocraticRepublicOfKorea, "850" }, { QLocale::RepublicOfKorea, "82" }, { QLocale::Kuwait, "965" }, { QLocale::Kyrgyzstan, "996" }, { QLocale::Laos, "856" }, { QLocale::Latvia, "371" }, { QLocale::Lebanon, "961" }, { QLocale::Lesotho, "266" }, { QLocale::Liberia, "231" }, { QLocale::Libya, "218" }, { QLocale::Liechtenstein, "423" }, { QLocale::Lithuania, "370" }, { QLocale::Luxembourg, "352" }, { QLocale::Macau, "853" }, { QLocale::Macedonia, "389" }, { QLocale::Madagascar, "261" }, { QLocale::Malawi, "265" }, { QLocale::Malaysia, "60" }, { QLocale::Maldives, "960" }, { QLocale::Mali, "223" }, { QLocale::Malta, "356" }, { QLocale::MarshallIslands, "692" }, { QLocale::Martinique, "596" }, { QLocale::Mauritania, "222" }, { QLocale::Mauritius, "230" }, { QLocale::Mayotte, "262" }, { QLocale::Mexico, "52" }, { QLocale::Micronesia, "691" }, { QLocale::Moldova, "373" }, { QLocale::Monaco, "377" }, { QLocale::Mongolia, "976" }, { QLocale::Montenegro, "382" }, { QLocale::Montserrat, "664" }, { QLocale::Morocco, "212" }, { QLocale::Mozambique, "258" }, { QLocale::Myanmar, "95" }, { QLocale::Namibia, "264" }, { QLocale::NauruCountry, "674" }, { QLocale::Nepal, "43" }, { QLocale::Netherlands, "31" }, { QLocale::NewCaledonia, "687" }, { QLocale::NewZealand, "64" }, { QLocale::Nicaragua, "505" }, { QLocale::Niger, "227" }, { QLocale::Nigeria, "234" }, { QLocale::Niue, "683" }, { QLocale::NorfolkIsland, "672" }, { QLocale::NorthernMarianaIslands, "1" }, { QLocale::Norway, "47" }, { QLocale::Oman, "968" }, { QLocale::Pakistan, "92" }, { QLocale::Palau, "680" }, { QLocale::PalestinianTerritories, "970" }, { QLocale::Panama, "507" }, { QLocale::PapuaNewGuinea, "675" }, { QLocale::Paraguay, "595" }, { QLocale::Peru, "51" }, { QLocale::Philippines, "63" }, { QLocale::Poland, "48" }, { QLocale::Portugal, "351" }, { QLocale::PuertoRico, "1" }, { QLocale::Qatar, "974" }, { QLocale::Reunion, "262" }, { QLocale::Romania, "40" }, { QLocale::RussianFederation, "7" }, { QLocale::Rwanda, "250" }, { QLocale::SaintHelena, "290" }, { QLocale::SaintKittsAndNevis, "1" }, { QLocale::SaintLucia, "1" }, { QLocale::SaintPierreAndMiquelon, "508" }, { QLocale::SaintVincentAndTheGrenadines, "1" }, { QLocale::Samoa, "685" }, { QLocale::SanMarino, "378" }, { QLocale::SaoTomeAndPrincipe, "239" }, { QLocale::SaudiArabia, "966" }, { QLocale::Senegal, "221" }, { QLocale::Serbia, "381" }, { QLocale::Seychelles, "248" }, { QLocale::SierraLeone, "232" }, { QLocale::Singapore, "65" }, { QLocale::Slovakia, "421" }, { QLocale::Slovenia, "386" }, { QLocale::SolomonIslands, "677" }, { QLocale::Somalia, "252" }, { QLocale::SouthAfrica, "27" }, { QLocale::Spain, "34" }, { QLocale::SriLanka, "94" }, { QLocale::Sudan, "249" }, { QLocale::Suriname, "597" }, { QLocale::Swaziland, "268" }, { QLocale::Sweden, "46" }, { QLocale::Switzerland, "41" }, { QLocale::Syria, "963" }, { QLocale::Taiwan, "886" }, { QLocale::Tajikistan, "992" }, { QLocale::Tanzania, "255" }, { QLocale::Thailand, "66" }, { QLocale::Togo, "228" }, { QLocale::Tokelau, "690" }, { QLocale::Tonga, "676" }, { QLocale::TrinidadAndTobago, "1" }, { QLocale::Tunisia, "216" }, { QLocale::Turkey, "90" }, { QLocale::Turkmenistan, "993" }, { QLocale::TurksAndCaicosIslands, "1" }, { QLocale::Tuvalu, "688" }, { QLocale::Uganda, "256" }, { QLocale::Ukraine, "380" }, { QLocale::UnitedArabEmirates, "971" }, { QLocale::UnitedKingdom, "44" }, { QLocale::UnitedStates, "1" }, { QLocale::Uruguay, "598" }, { QLocale::Uzbekistan, "998" }, { QLocale::Vanuatu, "678" }, { QLocale::Venezuela, "58" }, { QLocale::Vietnam, "84" }, { QLocale::WallisAndFutunaIslands, "681" }, { QLocale::Yemen, "967" }, { QLocale::Zambia, "260" }, { QLocale::Zimbabwe, "263" } }; // ----------------------------------------------------------------------------- TelephoneNumbersModel::TelephoneNumbersModel (QObject *parent) : QAbstractListModel(parent) {} int TelephoneNumbersModel::rowCount (const QModelIndex &) const { return mCountryCodes.count(); } QHash TelephoneNumbersModel::roleNames () const { QHash roles; roles[Qt::DisplayRole] = "$phoneNumber"; return roles; } QVariant TelephoneNumbersModel::data (const QModelIndex &index, int role) const { int row = index.row(); if (!index.isValid() || row < 0 || row >= mCountryCodes.count()) return QVariant(); if (role == Qt::DisplayRole) { const QPair &countryCode = mCountryCodes[row]; QVariantMap map; map["countryCode"] = countryCode.second; map["countryName"] = QStringLiteral("%1 (+%2)") .arg(Utils::getCountryName(countryCode.first)) .arg(countryCode.second); return map; } return QVariant(); } int TelephoneNumbersModel::getDefaultIndex () const { QLocale::Country country = QLocale().country(); const auto it = find_if( mCountryCodes.cbegin(), mCountryCodes.cend(), [&country](const QPair &pair) { return country == pair.first; } ); return it != mCountryCodes.cend() ? int(distance(mCountryCodes.cbegin(), it)) : 0; } linphone-desktop-4.2.5/linphone-app/src/components/telephone-numbers/TelephoneNumbersModel.hpp000066400000000000000000000030441376717241300327740ustar00rootroot00000000000000/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef TELEPHONE_NUMBERS_MODEL_H_ #define TELEPHONE_NUMBERS_MODEL_H_ #include #include // ============================================================================= class TelephoneNumbersModel : public QAbstractListModel { Q_OBJECT; Q_PROPERTY(int defaultIndex READ getDefaultIndex CONSTANT); public: TelephoneNumbersModel (QObject *parent = Q_NULLPTR); int rowCount (const QModelIndex &index = QModelIndex()) const override; QHash roleNames () const override; QVariant data (const QModelIndex &index, int role = Qt::DisplayRole) const override; private: int getDefaultIndex () const; static const QList> mCountryCodes; }; #endif // ifndef TELEPHONE_NUMBERS_MODEL_H_ linphone-desktop-4.2.5/linphone-app/src/components/timeline/000077500000000000000000000000001376717241300241745ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/src/components/timeline/TimelineModel.cpp000066400000000000000000000076331376717241300274400ustar00rootroot00000000000000/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "components/core/CoreManager.hpp" #include "components/settings/AccountSettingsModel.hpp" #include "components/sip-addresses/SipAddressesModel.hpp" #include "utils/Utils.hpp" #include "TimelineModel.hpp" #include // ============================================================================= TimelineModel::TimelineModel (QObject *parent) : QSortFilterProxyModel(parent) { CoreManager *coreManager = CoreManager::getInstance(); AccountSettingsModel *accountSettingsModel = coreManager->getAccountSettingsModel(); QObject::connect(accountSettingsModel, &AccountSettingsModel::accountSettingsUpdated, this, [this]() { handleLocalAddressChanged(CoreManager::getInstance()->getAccountSettingsModel()->getUsedSipAddressAsStringUriOnly()); }); QObject::connect(coreManager->getSipAddressesModel(), &SipAddressesModel::sipAddressReset, this, [this]() { invalidate();// Invalidate and reload GUI if the model has been reset }); mLocalAddress = accountSettingsModel->getUsedSipAddressAsStringUriOnly(); setSourceModel(coreManager->getSipAddressesModel()); sort(0); } QHash TimelineModel::roleNames () const { QHash roles; roles[Qt::DisplayRole] = "$timelineEntry"; return roles; } // ----------------------------------------------------------------------------- static inline const QHash *getLocalToConferenceEntry (const QVariantMap &map) { return map.value("__localToConferenceEntry").value(); } QVariant TimelineModel::data (const QModelIndex &index, int role) const { QVariantMap map(QSortFilterProxyModel::data(index, role).toMap()); auto localToConferenceEntry = getLocalToConferenceEntry(map); auto it = localToConferenceEntry->find(getCleanedLocalAddress()); if (it != localToConferenceEntry->end()) { map["timestamp"] = it->timestamp; map["isComposing"] = it->isComposing; map["unreadMessageCount"] = it->unreadMessageCount; map["missedCallCount"] = it->missedCallCount; } return map; } bool TimelineModel::filterAcceptsRow (int sourceRow, const QModelIndex &sourceParent) const { const QModelIndex index = sourceModel()->index(sourceRow, 0, sourceParent); return getLocalToConferenceEntry(index.data().toMap())->contains(getCleanedLocalAddress()); } bool TimelineModel::lessThan (const QModelIndex &left, const QModelIndex &right) const { QString localAddress = getCleanedLocalAddress(); const QDateTime &a(getLocalToConferenceEntry(sourceModel()->data(left).toMap())->find(localAddress)->timestamp); const QDateTime &b(getLocalToConferenceEntry(sourceModel()->data(right).toMap())->find(localAddress)->timestamp); return a > b; } // ----------------------------------------------------------------------------- QString TimelineModel::getLocalAddress () const { return mLocalAddress; } QString TimelineModel::getCleanedLocalAddress () const { return Utils::cleanSipAddress(mLocalAddress); } void TimelineModel::handleLocalAddressChanged (const QString &localAddress) { if (mLocalAddress != localAddress) { mLocalAddress = localAddress; invalidate(); } } linphone-desktop-4.2.5/linphone-app/src/components/timeline/TimelineModel.hpp000066400000000000000000000033621376717241300274400ustar00rootroot00000000000000/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef TIMELINE_MODEL_H_ #define TIMELINE_MODEL_H_ #include // ============================================================================= class TimelineModel : public QSortFilterProxyModel { Q_OBJECT; Q_PROPERTY(QString localAddress READ getLocalAddress NOTIFY localAddressChanged); public: TimelineModel (QObject *parent = Q_NULLPTR); QHash roleNames () const override; signals: void localAddressChanged (const QString &localAddress); protected: QVariant data (const QModelIndex &index, int role = Qt::DisplayRole) const override; bool filterAcceptsRow (int sourceRow, const QModelIndex &sourceParent) const override; bool lessThan (const QModelIndex &left, const QModelIndex &right) const override; QString getLocalAddress () const; QString getCleanedLocalAddress () const; void handleLocalAddressChanged (const QString &localAddress); private: QString mLocalAddress; }; #endif // TIMELINE_MODEL_H_ linphone-desktop-4.2.5/linphone-app/src/components/url-handlers/000077500000000000000000000000001376717241300247665ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/src/components/url-handlers/UrlHandlers.cpp000066400000000000000000000023121376717241300277130ustar00rootroot00000000000000/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include #include "components/sip-addresses/SipAddressesModel.hpp" #include "UrlHandlers.hpp" // ============================================================================= UrlHandlers::UrlHandlers (QObject *parent) : QObject(parent) { QDesktopServices::setUrlHandler("sip", this, "handleSip"); } void UrlHandlers::handleSip (const QUrl &url) { emit sip(SipAddressesModel::interpretSipAddress(url)); } linphone-desktop-4.2.5/linphone-app/src/components/url-handlers/UrlHandlers.hpp000066400000000000000000000022331376717241300277220ustar00rootroot00000000000000/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef URL_HANDLERS_H_ #define URL_HANDLERS_H_ #include // ============================================================================= class UrlHandlers : public QObject { Q_OBJECT; public: UrlHandlers (QObject *parent = Q_NULLPTR); public slots: void handleSip (const QUrl &url); signals: void sip (const QString &sipAddress); }; #endif // URL_HANDLERS_H_ linphone-desktop-4.2.5/linphone-app/src/config.h.cmake000066400000000000000000000026461376717241300227060ustar00rootroot00000000000000/******************************************************************************* * config.h.cmake * Copyright (C) 2017-2018 Belledonne Communications, Grenoble France * ******************************************************************************** * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * *******************************************************************************/ #cmakedefine APPLICATION_DESCRIPTION "${APPLICATION_DESCRIPTION}" #cmakedefine APPLICATION_ID "${APPLICATION_ID}" #cmakedefine APPLICATION_NAME "${APPLICATION_NAME}" #cmakedefine APPLICATION_VENDOR "${APPLICATION_VENDOR}" #cmakedefine APPLICATION_URL "${APPLICATION_URL}" #cmakedefine ENABLE_UPDATE_CHECK 1 #cmakedefine EXECUTABLE_NAME "${EXECUTABLE_NAME}" #cmakedefine MSPLUGINS_DIR "${MSPLUGINS_DIR}" linphone-desktop-4.2.5/linphone-app/src/utils/000077500000000000000000000000001376717241300213415ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/src/utils/LinphoneUtils.cpp000066400000000000000000000024311376717241300246420ustar00rootroot00000000000000/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include #include "LinphoneUtils.hpp" // ============================================================================= linphone::TransportType LinphoneUtils::stringToTransportType (const QString &transport) { if (transport == QLatin1String("TCP")) return linphone::TransportType::Tcp; if (transport == QLatin1String("UDP")) return linphone::TransportType::Udp; if (transport == QLatin1String("TLS")) return linphone::TransportType::Tls; return linphone::TransportType::Dtls; } linphone-desktop-4.2.5/linphone-app/src/utils/LinphoneUtils.hpp000066400000000000000000000022621376717241300246510ustar00rootroot00000000000000/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef LINPHONE_UTILS_H_ #define LINPHONE_UTILS_H_ #include // ============================================================================= class QString; namespace LinphoneUtils { linphone::TransportType stringToTransportType (const QString &transport); static constexpr char WindowIconPath[] = ":/assets/images/linphone_logo.svg"; } #endif // ifndef LINPHONE_UTILS_H_ linphone-desktop-4.2.5/linphone-app/src/utils/MediastreamerUtils.cpp000066400000000000000000000113221376717241300256470ustar00rootroot00000000000000/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include #include "mediastreamer2/msvolume.h" #include "mediastreamer2/mssndcard.h" #include "mediastreamer2/msticker.h" #include "components/core/CoreManager.hpp" #include "MediastreamerUtils.hpp" #include using namespace MediastreamerUtils; SimpleCaptureGraph::SimpleCaptureGraph(const std::string &capture, const std::string &playback) : captureCardId(capture), playbackCardId(playback) { LinphoneCore *ccore = CoreManager::getInstance()->getCore()->cPtr(); msFactory = linphone_core_get_ms_factory(ccore); playbackCard = ms_snd_card_manager_get_card(ms_factory_get_snd_card_manager(msFactory), playbackCardId.c_str()); if (!playbackCard) qWarning("Cannot get playback card from MSFactory with : %s", playbackCardId.c_str()); captureCard = ms_snd_card_manager_get_card(ms_factory_get_snd_card_manager(msFactory), captureCardId.c_str()); if (!captureCard) qWarning("Cannot get capture card from MSFactory with : %s", captureCardId.c_str()); if(playbackCard && captureCard)// Assure to initialize when playback and capture are available init(); } SimpleCaptureGraph::~SimpleCaptureGraph() { destroy(); } void SimpleCaptureGraph::init() { if (!audioCapture) { audioCapture = ms_snd_card_create_reader(captureCard); } if (!audioSink) { audioSink = ms_snd_card_create_writer(playbackCard); } if (!captureVolumeFilter) { captureVolumeFilter = ms_factory_create_filter(msFactory, MS_VOLUME_ID); } if (!playbackVolumeFilter) { playbackVolumeFilter = ms_factory_create_filter(msFactory, MS_VOLUME_ID); } ms_filter_link(audioCapture, 0, captureVolumeFilter, 0); ms_filter_link(captureVolumeFilter, 0, playbackVolumeFilter, 0); ms_filter_link(playbackVolumeFilter, 0, audioSink, 0); //Mute playback float muteGain = 0.0f; ms_filter_call_method(playbackVolumeFilter, static_cast(MS_VOLUME_SET_GAIN), &muteGain); ticker = ms_ticker_new(); running = false; } void SimpleCaptureGraph::start() { if (!running && audioCapture) { running = true; ms_ticker_attach(ticker, audioCapture); } } void SimpleCaptureGraph::stop() { if (running && audioCapture){ ms_ticker_detach(ticker, audioCapture); running = false; } } void SimpleCaptureGraph::destroy() { if (running) { stop(); } if (audioSink) ms_filter_unlink(playbackVolumeFilter, 0, audioSink, 0); if (captureVolumeFilter && playbackVolumeFilter) ms_filter_unlink(captureVolumeFilter, 0, playbackVolumeFilter, 0); if (audioCapture) ms_filter_unlink(audioCapture, 0, captureVolumeFilter, 0); if (playbackVolumeFilter) ms_filter_destroy(playbackVolumeFilter); if (captureVolumeFilter) ms_filter_destroy(captureVolumeFilter); if (audioSink) ms_filter_destroy(audioSink); if (audioCapture) ms_filter_destroy(audioCapture); if (ticker) { ms_ticker_destroy(ticker);// Destroy ticker at the end to avoid conflicts between attached filters } ticker = nullptr; playbackVolumeFilter = nullptr; captureVolumeFilter = nullptr; audioSink = nullptr; audioCapture = nullptr; } float SimpleCaptureGraph::getCaptureGain() { float gain = 0.0f; if (isRunning() && audioCapture) { ms_filter_call_method(audioCapture, MS_AUDIO_CAPTURE_GET_VOLUME_GAIN, &gain); } return gain; } void SimpleCaptureGraph::setCaptureGain(float gain) { if (isRunning() && audioCapture) { ms_filter_call_method(audioCapture, MS_AUDIO_CAPTURE_SET_VOLUME_GAIN, &gain); } } float SimpleCaptureGraph::getPlaybackGain() { float gain = 0.0f; if (isRunning() && audioSink) { ms_filter_call_method(audioSink, MS_AUDIO_PLAYBACK_GET_VOLUME_GAIN, &gain); } return gain; } void SimpleCaptureGraph::setPlaybackGain(float gain) { if (isRunning() && audioSink) { ms_filter_call_method(audioSink, MS_AUDIO_PLAYBACK_SET_VOLUME_GAIN, &gain); } } float SimpleCaptureGraph::getCaptureVolume() { float vol = 0; if (captureVolumeFilter) { ms_filter_call_method(captureVolumeFilter, MS_VOLUME_GET, &vol); vol = MediastreamerUtils::dbToLinear(vol); } return vol; } linphone-desktop-4.2.5/linphone-app/src/utils/MediastreamerUtils.hpp000066400000000000000000000051601376717241300256570ustar00rootroot00000000000000/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef MEDIASTREAMER_UTILS_H_ #define MEDIASTREAMER_UTILS_H_ #include #include "mediastreamer2/mssndcard.h" #include "mediastreamer2/msvolume.h" #include "mediastreamer2/msfilter.h" #include "mediastreamer2/msticker.h" #include #include // ============================================================================= namespace MediastreamerUtils { inline float computeVu (float volume) { constexpr float VuMin = -20.f; constexpr float VuMax = 4.f; if (volume < VuMin) return 0.f; if (volume > VuMax) return 1.f; return (volume - VuMin) / (VuMax - VuMin); } inline float dbToLinear(float volume) { return static_cast(pow(10.0, volume / 10.0)); } inline float linearToDb(float volume) { if (qFuzzyIsNull(volume)) { return MS_VOLUME_DB_LOWEST; } return static_cast(10.0 * log10(volume)); } //Simple mediastreamer audio capture graph //Used to get current microphone volume in audio settings class SimpleCaptureGraph { public: SimpleCaptureGraph(const std::string &captureCardId, const std::string &playbackCardId); ~SimpleCaptureGraph(); void start(); void stop(); float getCaptureVolume(); float getCaptureGain(); float getPlaybackGain(); void setCaptureGain(float volume); void setPlaybackGain(float volume); bool isRunning() const { return running; } protected: void init(); void destroy(); bool running = false; std::string captureCardId; std::string playbackCardId; MSFilter *audioSink = nullptr; MSFilter *audioCapture = nullptr; MSFilter *captureVolumeFilter = nullptr; MSFilter *playbackVolumeFilter = nullptr; MSTicker *ticker = nullptr; MSSndCard *playbackCard = nullptr; MSSndCard *captureCard = nullptr; MSFactory *msFactory = nullptr; }; } #endif // ifndef MEDIASTREAMER_UTILS_H_ linphone-desktop-4.2.5/linphone-app/src/utils/QExifImageHeader.cpp000066400000000000000000001445561376717241300251540ustar00rootroot00000000000000/**************************************************************************** ** ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the Qt scene graph research project. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions ** contained in the Technology Preview License Agreement accompanying ** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. ** ** ** ** ** ** ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ // This file was copied from Qt Extended 4.5 #include #include #include #include #include #include #include #include "Utils.hpp" #include "QExifImageHeader.hpp" /*! \typedef QExifSRational A synonym for \c QPair representing a signed rational number as stored in EXIF headers. The first integer in the pair is the numerator and the second the denominator. */ /*! \typedef QExifURational A synonym for \c QPair representing an unsigned rational number as stored in EXIF headers. The first integer in the pair is the numerator and the second the denominator. */ struct ExifIfdHeader { quint16 tag; quint16 type; quint32 count; union { quint32 offset; quint8 offsetBytes[4]; char offsetAscii[4]; quint16 offsetShorts[2]; }; }; QDataStream &operator>> (QDataStream &stream, ExifIfdHeader &header) { stream >> header.tag; stream >> header.type; stream >> header.count; if (header.type == QExifValue::Byte && header.count <= 4) { stream.readRawData(header.offsetAscii, 4); } else if (header.type == QExifValue::Ascii && header.count <= 4) { stream.readRawData(header.offsetAscii, 4); } else if (header.type == QExifValue::Short && header.count <= 2) { stream >> header.offsetShorts[0]; stream >> header.offsetShorts[1]; } else { stream >> header.offset; } return stream; } class QExifValuePrivate : public QSharedData { public: QExifValuePrivate (quint16 t, int c) : type(t), count(c) {} virtual ~QExifValuePrivate () {} quint16 type; int count; }; class QExifByteValuePrivate : public QExifValuePrivate { public: QExifByteValuePrivate () : QExifValuePrivate(QExifValue::Byte, 0) { ref.ref(); } QExifByteValuePrivate (const QVector &v) : QExifValuePrivate(QExifValue::Byte, v.size()), value(v) {} ~QExifByteValuePrivate(){} QVector value; }; class QExifUndefinedValuePrivate : public QExifValuePrivate { public: QExifUndefinedValuePrivate (const QByteArray &v) : QExifValuePrivate(QExifValue::Undefined, v.size()), value(v) {} QByteArray value; }; class QExifAsciiValuePrivate : public QExifValuePrivate { public: QExifAsciiValuePrivate (const QString &v) : QExifValuePrivate(QExifValue::Ascii, v.size() + 1), value(v) {} QString value; }; class QExifShortValuePrivate : public QExifValuePrivate { public: QExifShortValuePrivate (const QVector &v) : QExifValuePrivate(QExifValue::Short, v.size()), value(v) {} QVector value; }; class QExifLongValuePrivate : public QExifValuePrivate { public: QExifLongValuePrivate (const QVector &v) : QExifValuePrivate(QExifValue::Long, v.size()), value(v) {} QVector value; }; class QExifSignedLongValuePrivate : public QExifValuePrivate { public: QExifSignedLongValuePrivate (const QVector &v) : QExifValuePrivate(QExifValue::SignedLong, v.size()), value(v) {} QVector value; }; class QExifRationalValuePrivate : public QExifValuePrivate { public: QExifRationalValuePrivate (const QVector &v) : QExifValuePrivate(QExifValue::Rational, v.size()), value(v) {} QVector value; }; class QExifSignedRationalValuePrivate : public QExifValuePrivate { public: QExifSignedRationalValuePrivate (const QVector &v) : QExifValuePrivate(QExifValue::SignedRational, v.size()), value(v) {} QVector value; }; Q_GLOBAL_STATIC(QExifByteValuePrivate, qExifValuePrivateSharedNull) /*! \class QExifValue \inpublicgroup QtBaseModule \brief The QExifValue class represents data types found in EXIF image headers. Tag values in EXIF headers are stored as arrays of a limited number of data types. QExifValue encapsulates a union of these types and provides conversions to and from appropriate Qt types. \section1 String encoding Most tags with string values in EXIF headers are ASCII encoded and have the Ascii value type, but some tags allow other encodings. In this case the value type is Undefined and the encoding of the text is given by the encoding function(). \section1 Date-time values Date-time values in EXIF headers are stored in ASCII encoded strings of the form \c {yyyy:MM:dd HH:mm:ss}. Constructing a QExifValue from a QDateTime will perform this conversion and likewise an appropriately formed QExifValue can be converted to a QDateTime using the toDateTime() function. \sa QExifImageHeader \preliminary */ /*! \enum QExifValue::Type Enumerates the possible types of EXIF values. \value Byte An unsigned 8 bit integer. \value Ascii A null terminated ascii string. \value Short An unsigned 16 bit integer. \value Long An unsigned 32 bit integer. \value Rational Two unsigned 32 bit integers, representing a the numerator and denominator of an unsigned rational number. \value Undefined An array of 8 bit integers. \value SignedLong A signed 32 bit integer. \value SignedRational Two signed 32 bit integers representing the numerator and denominator of a signed rational number. */ /*! \enum QExifValue::TextEncoding Enumerates the encodings of text strings in EXIF values of Undefined type. \value NoEncoding An ASCII string of Ascii type. \value AsciiEncoding An ASCII string of Undefined type. \value JisEncoding A JIS X208-1990 string of Undefined type. \value UnicodeEncoding A Unicode string of Undefined type. \value UndefinedEncoding An unspecified string encoding of Undefined type. Assumed to be the local 8-bit encoding. */ /*! Constructs a null QExifValue. */ QExifValue::QExifValue () : d(qExifValuePrivateSharedNull()) {} /*! Constructs a QExifValue with a \a value of type Byte. */ QExifValue::QExifValue (quint8 value) : d(new QExifByteValuePrivate(QVector(1, value))) {} /*! Constructs a QExifValue with an array of \a values of type Byte. */ QExifValue::QExifValue (const QVector &values) : d(new QExifByteValuePrivate(values)) {} /*! Constructs a QExifValue with a \a value of type Ascii or Undefined. If the \a encoding is NoEncoding the value will be of type Ascii, otherwise it will be Undefined and the string encoded using the given \a encoding. */ QExifValue::QExifValue (const QString &value, TextEncoding encoding) : d(qExifValuePrivateSharedNull()) { switch (encoding) { case AsciiEncoding: d = new QExifUndefinedValuePrivate(QByteArray::fromRawData("ASCII\0\0\0", 8) + value.toUtf8()); break; case JisEncoding: { QTextCodec *codec = QTextCodec::codecForName("JIS X 0208"); if (codec) d = new QExifUndefinedValuePrivate(QByteArray::fromRawData("JIS\0\0\0\0\0", 8) + codec->fromUnicode(value)); } break; case UnicodeEncoding: { QTextCodec *codec = QTextCodec::codecForName("UTF-16"); if (codec) d = new QExifUndefinedValuePrivate(QByteArray::fromRawData("UNICODE\0", 8) + codec->fromUnicode(value)); } break; case UndefinedEncoding: d = new QExifUndefinedValuePrivate(QByteArray::fromRawData("\0\0\0\0\0\0\0\\0", 8) + value.toLocal8Bit()); break; default: d = new QExifAsciiValuePrivate(value); } } /*! Constructs a QExifValue with a \a value of type Short. */ QExifValue::QExifValue (quint16 value) : d(new QExifShortValuePrivate(QVector(1, value))) {} /*! Constructs a QExifValue with an array of \a values of type Short. */ QExifValue::QExifValue (const QVector &values) : d(new QExifShortValuePrivate(values)) {} /*! Constructs a QExifValue with a \a value of type Long. */ QExifValue::QExifValue (quint32 value) : d(new QExifLongValuePrivate(QVector(1, value))) {} /*! Constructs a QExifValue with an array of \a values of type Long. */ QExifValue::QExifValue (const QVector &values) : d(new QExifLongValuePrivate(values)) {} /*! Constructs a QExifValue with a \a value of type Rational. */ QExifValue::QExifValue (const QExifURational &value) : d(new QExifRationalValuePrivate(QVector(1, value))) {} /*! Constructs a QExifValue with an array of \a values of type Rational. */ QExifValue::QExifValue (const QVector &values) : d(new QExifRationalValuePrivate(values)) {} /*! Constructs a QExifValue with a \a value of type Undefined. */ QExifValue::QExifValue (const QByteArray &value) : d(new QExifUndefinedValuePrivate(value)) {} /*! Constructs a QExifValue with a \a value of type SignedLong. */ QExifValue::QExifValue (qint32 value) : d(new QExifSignedLongValuePrivate(QVector(1, value))) {} /*! Constructs a QExifValue with an array of \a values of type SignedLong. */ QExifValue::QExifValue (const QVector &values) : d(new QExifSignedLongValuePrivate(values)) {} /*! Constructs a QExifValue with a \a value of type SignedRational. */ QExifValue::QExifValue (const QExifSRational &value) : d(new QExifSignedRationalValuePrivate(QVector(1, value))) {} /*! Constructs a QExifValue with an array of \a values of type SignedRational. */ QExifValue::QExifValue (const QVector &values) : d(new QExifSignedRationalValuePrivate(values)) {} /*! Constructs a QExifValue of type Ascii with an ascii string formatted from a date-time \a value. Date-times are stored as strings in the format \c {yyyy:MM:dd HH:mm:ss}. */ QExifValue::QExifValue (const QDateTime &value) : d(new QExifAsciiValuePrivate(value.toString(QLatin1String("yyyy:MM:dd HH:mm:ss")))) {} /*! Constructs a copy of the QExifValue \a other. */ QExifValue::QExifValue (const QExifValue &other) : d(other.d) {} /*! Assigns the value of \a other to a QExifValue. */ QExifValue &QExifValue::operator= (const QExifValue &other) { d = other.d; return *this; } /*! Destroys a QExifValue. */ QExifValue::~QExifValue () {} /*! Compares a QExifValue to \a other. Returns true if they are the same value and false otherwise. */ bool QExifValue::operator== (const QExifValue &other) const { return d == other.d; } /*! Returns true if a QExifValue has a null value and false otherwise. */ bool QExifValue::isNull () const { return d == qExifValuePrivateSharedNull(); } /*! Returns the type of a QExifValue. */ int QExifValue::type () const { return d->type; } /*! Returns the number of elements in a QExifValue. For ascii strings this is the length of the string including the terminating null. */ int QExifValue::count () const { return d->count; } /*! Returns the encoding of strings stored in Undefined values. */ QExifValue::TextEncoding QExifValue::encoding () const { if (d->type == Undefined && d->count > 8) { QByteArray value = static_cast(d.constData())->value; if (value.startsWith(QByteArray::fromRawData("ASCII\0\0\0", 8))) return AsciiEncoding; else if (value.startsWith(QByteArray::fromRawData("JIS\0\0\0\0\0", 8))) return JisEncoding; else if (value.startsWith(QByteArray::fromRawData("UNICODE\0", 8))) return UnicodeEncoding; else if (value.startsWith(QByteArray::fromRawData("\0\0\0\0\0\0\0\0", 8))) return UndefinedEncoding; } return NoEncoding; } /*! Returns the value of a single element QExifValue of type Byte. */ quint8 QExifValue::toByte () const { return d->type == Byte && d->count == 1 ? static_cast(d.constData())->value.at(0) : 0; } /*! Returns the value of a multiple element QExifValue of type Byte. */ QVector QExifValue::toByteVector () const { return d->type == Byte ? static_cast(d.constData())->value : QVector(); } /*! Returns the value of a QExifValue of type Ascii. */ QString QExifValue::toString () const { switch (d->type) { case Ascii: return static_cast(d.constData())->value; case Undefined: { QByteArray string = static_cast(d.constData())->value.mid(8); switch (encoding()) { case AsciiEncoding: return QString::fromUtf8(string.constData(), string.length()); case JisEncoding: { QTextCodec *codec = QTextCodec::codecForName("JIS X 0208"); if (codec) return codec->toUnicode(string); } break; case UnicodeEncoding: { QTextCodec *codec = QTextCodec::codecForName("UTF-16"); if (codec) return codec->toUnicode(string); return QString::fromLocal8Bit(string.constData(), string.length()); } case UndefinedEncoding: return QString::fromLocal8Bit(string.constData(), string.length()); default: break; } return QString(); } default: return QString(); } } /*! Returns the value of a single element QExifValue of type Byte or Short. */ quint16 QExifValue::toShort () const { if (d->count == 1) { switch (d->type) { case Byte: return static_cast(d.constData())->value.at(0); case Short: return static_cast(d.constData())->value.at(0); } } return 0; } /*! Returns the value of a single element QExifValue of type Short. */ QVector QExifValue::toShortVector () const { return d->type == Short ? static_cast(d.constData())->value : QVector(); } /*! Returns the value of a single element QExifValue of type Byte, Short, Long, or SignedLong. */ quint32 QExifValue::toLong () const { if (d->count == 1) { switch (d->type) { case Byte: return static_cast(d.constData())->value.at(0); case Short: return static_cast(d.constData())->value.at(0); case Long: return static_cast(d.constData())->value.at(0); case SignedLong: return quint32(static_cast(d.constData())->value.at(0)); } } return 0; } /*! Returns the value of a multiple element QExifValue of type Long. */ QVector QExifValue::toLongVector () const { return d->type == Long ? static_cast(d.constData())->value : QVector(); } /*! Returns the value of a multiple element QExifValue of type Rational. */ QExifURational QExifValue::toRational () const { return d->type == Rational && d->count == 1 ? static_cast(d.constData())->value.at(0) : QExifURational(); } /*! Returns the value of a multiple element QExifValue of type Rational. */ QVector QExifValue::toRationalVector () const { return d->type == Rational ? static_cast(d.constData())->value : QVector(); } /*! Returns the value of a QExifValue of type Undefined. */ QByteArray QExifValue::toByteArray () const { switch (d->type) { case Ascii: return static_cast(d.constData())->value.toUtf8(); case Undefined: return static_cast(d.constData())->value; default: return QByteArray(); } } /*! Returns the value of a single element QExifValue of type Byte, Short, Long, or SignedLong. */ qint32 QExifValue::toSignedLong () const { if (d->count == 1) { switch (d->type) { case Byte: return static_cast(d.constData())->value.at(0); case Short: return static_cast(d.constData())->value.at(0); case Long: return qint32(static_cast(d.constData())->value.at(0)); case SignedLong: return static_cast(d.constData())->value.at(0); } } return 0; } /*! Returns the value of a multiple element QExifValue of type SignedLong. */ QVector QExifValue::toSignedLongVector () const { return d->type == SignedLong ? static_cast(d.constData())->value : QVector(); } /*! Returns the value of a single element QExifValue of type SignedRational. */ QExifSRational QExifValue::toSignedRational () const { return d->type == SignedRational && d->count == 1 ? static_cast(d.constData())->value.at(0) : QExifSRational(); } /*! Returns the value of a multiple element QExifValue of type SignedRational. */ QVector QExifValue::toSignedRationalVector () const { return d->type == SignedRational ? static_cast(d.constData())->value : QVector(); } /*! Returns the value of QExifValue storing a date-time. Date-times are stored as ascii strings in the format \c {yyyy:MM:dd HH:mm:ss}. */ QDateTime QExifValue::toDateTime () const { return d->type == Ascii && d->count == 20 ? QDateTime::fromString(static_cast(d.constData())->value, QLatin1String("yyyy:MM:dd HH:mm:ss")) : QDateTime(); } class QExifImageHeaderPrivate { public: QSysInfo::Endian byteOrder; mutable qint64 size; QMap imageIfdValues; QMap exifIfdValues; QMap gpsIfdValues; QSize thumbnailSize; QByteArray thumbnailData; QExifValue thumbnailXResolution; QExifValue thumbnailYResolution; QExifValue thumbnailResolutionUnit; QExifValue thumbnailOrientation; }; /*! \class QExifImageHeader \inpublicgroup QtBaseModule \brief The QExifImageHeader class provides functionality for reading and writing EXIF image headers. EXIF headers are a collection of properties that describe the image they're embedded in. Each property is identified by a tag of which there are three kinds. \l {ImageTag}{Image tags} which mostly describe the format (dimensions, resolution, orientation) but also include some descriptive information (description, camera make and model, artist). \l {ExifExtendedTag} {EXIF extended tags} which elaborate on some of the image tags and record the camera settings at time of capture among other things. Finally there are \l {GpsTag}{GPS tags} which record the location the image was captured. EXIF tags are typically found in JPEG images but may be found in other image formats. To read headers from a JPEG image QExifImageHeader provides the loadFromJpeg() function, and the complementary saveToJpeg() function for writing. To allow reading and writing arbitrary formats QExifImageHeader provides the read() and write() functions which work with just the EXIF header data itself. \preliminary */ /*! \enum QExifImageHeader::ImageTag Enumerates the TIFF image tag IDs defined in the EXIF specification. \value ImageWidth \value ImageLength \value BitsPerSample \value Compression \value PhotometricInterpretation \value Orientation \value SamplesPerPixel \value PlanarConfiguration \value YCbCrSubSampling \value XResolution \value YResolution \value ResolutionUnit \value StripOffsets \value RowsPerStrip \value StripByteCounts \value TransferFunction \value WhitePoint \value PrimaryChromaciticies \value YCbCrCoefficients \value ReferenceBlackWhite \value DateTime \value ImageDescription \value Make \value Model \value Software \value Artist \value Copyright */ /*! \enum QExifImageHeader::ExifExtendedTag Enumerates the extended EXIF tag IDs defined in the EXIF specification. \value ExifVersion \value FlashPixVersion \value ColorSpace \value ComponentsConfiguration \value CompressedBitsPerPixel \value PixelXDimension \value PixelYDimension \value MakerNote \value UserComment \value RelatedSoundFile \value DateTimeOriginal \value DateTimeDigitized \value SubSecTime \value SubSecTimeOriginal \value SubSecTimeDigitized \value ImageUniqueId \value ExposureTime \value FNumber \value ExposureProgram \value SpectralSensitivity \value ISOSpeedRatings \value Oecf \value ShutterSpeedValue \value ApertureValue \value BrightnessValue \value ExposureBiasValue \value MaxApertureValue \value SubjectDistance \value MeteringMode \value LightSource \value Flash \value FocalLength \value SubjectArea \value FlashEnergy \value SpatialFrequencyResponse \value FocalPlaneXResolution \value FocalPlaneYResolution \value FocalPlaneResolutionUnit \value SubjectLocation \value ExposureIndex \value SensingMethod \value FileSource \value SceneType \value CfaPattern \value CustomRendered \value ExposureMode \value WhiteBalance \value DigitalZoomRatio \value FocalLengthIn35mmFilm \value SceneCaptureType \value GainControl \value Contrast \value Saturation \value Sharpness \value DeviceSettingDescription \value SubjectDistanceRange */ /*! \enum QExifImageHeader::GpsTag Enumerates the GPS tag IDs from the EXIF specification. \value GpsVersionId \value GpsLatitudeRef \value GpsLatitude \value GpsLongitudeRef \value GpsLongitude \value GpsAltitudeRef \value GpsAltitude \value GpsTimeStamp \value GpsSatellites \value GpsStatus \value GpsMeasureMode \value GpsDop \value GpsSpeedRef \value GpsSpeed \value GpsTrackRef \value GpsTrack \value GpsImageDirectionRef \value GpsImageDirection \value GpsMapDatum \value GpsDestLatitudeRef \value GpsDestLatitude \value GpsDestLongitudeRef \value GpsDestLongitude \value GpsDestBearingRef \value GpsDestBearing \value GpsDestDistanceRef \value GpsDestDistance \value GpsProcessingMethod \value GpsAreaInformation \value GpsDateStamp \value GpsDifferential */ /*! Constructs a new EXIF image data editor. */ QExifImageHeader::QExifImageHeader () : d(new QExifImageHeaderPrivate) { d->byteOrder = QSysInfo::ByteOrder; d->size = -1; } /*! Constructs a new EXIF image data editor and reads the meta-data from a JPEG image with the given \a fileName. */ QExifImageHeader::QExifImageHeader (const QString &fileName) : d(new QExifImageHeaderPrivate) { d->byteOrder = QSysInfo::ByteOrder; d->size = -1; loadFromJpeg(fileName); } /*! Destroys an EXIF image data editor. */ QExifImageHeader::~QExifImageHeader () { clear(); delete d; } /*! Reads meta-data from a JPEG image with the given \a fileName. Returns true if the data was successfully parsed and false otherwise. */ bool QExifImageHeader::loadFromJpeg (const QString &fileName) { QFile file(fileName); if (file.open(QIODevice::ReadOnly)) return loadFromJpeg(&file); else return false; } /*! Reads meta-data from an I/O \a device containing a JPEG image. Returns true if the data was successfully parsed and false otherwise. */ bool QExifImageHeader::loadFromJpeg (QIODevice *device) { clear(); QByteArray exifData = extractExif(device); if (!exifData.isEmpty()) { QBuffer buffer(&exifData); return buffer.open(QIODevice::ReadOnly) && read(&buffer); } return false; } /*! Saves meta-data to a JPEG image with the given \a fileName. Returns true if the data was successfully written. */ bool QExifImageHeader::saveToJpeg (const QString &fileName) const { QFile file(fileName); if (file.open(QIODevice::ReadWrite)) return saveToJpeg(&file); else return false; } /*! Save meta-data to the given I/O \a device. The device must be non-sequential and already contain a valid JPEG image. Returns true if the data was successfully written. */ bool QExifImageHeader::saveToJpeg (QIODevice *device) const { if (device->isSequential()) return false; QByteArray exif; { QBuffer buffer(&exif); if (!buffer.open(QIODevice::WriteOnly)) return false; write(&buffer); buffer.close(); exif = QByteArray::fromRawData("Exif\0\0", 6) + exif; } QDataStream stream(device); stream.setByteOrder(QDataStream::BigEndian); if (device->read(2) != "\xFF\xD8") // Not a valid JPEG image. return false; quint16 segmentId; quint16 segmentLength; stream >> segmentId; stream >> segmentLength; if (segmentId == 0xFFE0) { QByteArray jfif = device->read(segmentLength - 2); if (!jfif.startsWith("JFIF")) return false; stream >> segmentId; stream >> segmentLength; if (segmentId == 0xFFE1) { QByteArray oldExif = device->read(segmentLength - 2); if (!oldExif.startsWith("Exif")) return false; int dSize = oldExif.size() - exif.size(); if (dSize > 0) exif += QByteArray(dSize, '\0'); QByteArray remainder = device->readAll(); device->seek(0); stream << quint16(0xFFD8); // SOI stream << quint16(0xFFE0); // APP0 stream << quint16(jfif.size() + 2); device->write(jfif); stream << quint16(0xFFE1); // APP1 stream << quint16(exif.size() + 2); device->write(exif); device->write(remainder); } else { QByteArray remainder = device->readAll(); device->seek(0); stream << quint16(0xFFD8); // SOI stream << quint16(0xFFE0); // APP0 stream << quint16(jfif.size() + 2); device->write(jfif); stream << quint16(0xFFE1); // APP1 stream << quint16(exif.size() + 2); device->write(exif); stream << quint16(0xFFE0); // APP0 stream << segmentId; stream << segmentLength; device->write(remainder); } } else if (segmentId == 0xFFE1) { QByteArray oldExif = device->read(segmentLength - 2); if (!oldExif.startsWith("Exif")) return false; int dSize = oldExif.size() - exif.size(); if (dSize > 0) exif += QByteArray(dSize, '\0'); QByteArray remainder = device->readAll(); device->seek(0); stream << quint16(0xFFD8); // SOI stream << quint16(0xFFE1); // APP1 stream << quint16(exif.size() + 2); device->write(exif); device->write(remainder); } else { QByteArray remainder = device->readAll(); device->seek(0); stream << quint16(0xFFD8); // SOI stream << quint16(0xFFE1); // APP1 stream << quint16(exif.size() + 2); device->write(exif); stream << segmentId; stream << segmentLength; device->write(remainder); } return true; } /*! Returns the byte order of EXIF file. */ QSysInfo::Endian QExifImageHeader::byteOrder () const { return d->byteOrder; } quint32 QExifImageHeader::sizeOf (const QExifValue &value) const { switch (value.type()) { case QExifValue::Byte: case QExifValue::Undefined: return quint32(value.count() > 4 ? 12 + value.count() : 12); case QExifValue::Ascii: return quint32(value.count() > 4 ? 12 + value.count() : 12); case QExifValue::Short: return value.count() > 2 ? quint32(12 + quint32(value.count()) * sizeof(quint16)) : 12; case QExifValue::Long: case QExifValue::SignedLong: return value.count() > 1 ? quint32(12 + quint32(value.count()) * sizeof(quint32)) : 12; case QExifValue::Rational: case QExifValue::SignedRational: return value.count() > 0 ? quint32(12 + quint32(value.count()) * sizeof(quint32) * 2) : 12; default: return 0; } } template quint32 QExifImageHeader::calculateSize (const QMap &values) const { quint32 size = sizeof(quint16); foreach(const QExifValue &value, values) size += sizeOf(value); return size; } /*! Returns the size of EXIF data in bytes. */ qint64 QExifImageHeader::size () const { if (d->size == -1) { d->size = 2 + // Byte Order 2 + // Marker 4 + // Image Ifd offset 12 + // ExifIfdPointer Ifd 4 + // Thumbnail Ifd offset calculateSize(d->imageIfdValues) + // Image headers and values. calculateSize(d->exifIfdValues); // Exif headers and values. if (!d->gpsIfdValues.isEmpty()) { d->size += 12 + // GpsInfoIfdPointer Ifd calculateSize(d->gpsIfdValues); // Gps headers and values. } if (!d->thumbnailData.isEmpty()) { d->size += 2 + // Thumbnail Ifd count 12 + // Compression Ifd 20 + // XResolution Ifd 20 + // YResolution Ifd 12 + // ResolutionUnit Ifd 12 + // JpegInterchangeFormat Ifd 12 + // JpegInterchangeFormatLength Ifd d->thumbnailData.size(); // Thumbnail data size. } } return d->size; } /*! Clears all image meta-data. */ void QExifImageHeader::clear () { d->imageIfdValues.clear(); d->exifIfdValues.clear(); d->gpsIfdValues.clear(); d->thumbnailData.clear(); d->size = -1; } /*! Returns a list of all image tags in an EXIF header. */ QList QExifImageHeader::imageTags () const { return d->imageIfdValues.keys(); } /*! Returns a list of all extended EXIF tags in a header. */ QList QExifImageHeader::extendedTags () const { return d->exifIfdValues.keys(); } /*! Returns a list of all GPS tags in an EXIF header. */ QList QExifImageHeader::gpsTags () const { return d->gpsIfdValues.keys(); } /*! Returns true if an EXIf header contains a value for an image \a tag and false otherwise. */ bool QExifImageHeader::contains (ImageTag tag) const { return d->imageIfdValues.contains(tag); } /*! Returns true if a header contains a a value for an extended EXIF \a tag and false otherwise. */ bool QExifImageHeader::contains (ExifExtendedTag tag) const { return d->exifIfdValues.contains(tag); } /*! Returns true if an EXIf header contains a value for a GPS \a tag and false otherwise. */ bool QExifImageHeader::contains (GpsTag tag) const { return d->gpsIfdValues.contains(tag); } /*! Removes the value for an image \a tag. */ void QExifImageHeader::remove (ImageTag tag) { d->imageIfdValues.remove(tag); d->size = -1; } /*! Removes the value for an extended EXIF \a tag. */ void QExifImageHeader::remove (ExifExtendedTag tag) { d->exifIfdValues.remove(tag); d->size = -1; } /*! Removes the value for a GPS \a tag. */ void QExifImageHeader::remove (GpsTag tag) { d->gpsIfdValues.remove(tag); d->size = -1; } /*! Returns the value for an image \a tag. */ QExifValue QExifImageHeader::value (ImageTag tag) const { return d->imageIfdValues.value(tag); } /*! Returns the value for an extended EXIF \a tag. */ QExifValue QExifImageHeader::value (ExifExtendedTag tag) const { return d->exifIfdValues.value(tag); } /*! Returns the value for a GPS tag. */ QExifValue QExifImageHeader::value (GpsTag tag) const { return d->gpsIfdValues.value(tag); } /*! Sets the \a value for an image \a tag. */ void QExifImageHeader::setValue (ImageTag tag, const QExifValue &value) { d->imageIfdValues[tag] = value; d->size = -1; } /*! Sets the \a value for an extended EXIF \a tag. */ void QExifImageHeader::setValue (ExifExtendedTag tag, const QExifValue &value) { d->exifIfdValues[tag] = value; d->size = -1; } /*! Sets the \a value for an GPS \a tag. */ void QExifImageHeader::setValue (GpsTag tag, const QExifValue &value) { d->gpsIfdValues[tag] = value; d->size = -1; } /*! Returns the image thumbnail. */ QImage QExifImageHeader::thumbnail () const { QImage image; image.loadFromData(d->thumbnailData, "JPG"); if (!d->thumbnailOrientation.isNull()) { switch (d->thumbnailOrientation.toShort()) { case 1: return image; case 2: return image.transformed(QTransform().rotate(180, Qt::YAxis)); case 3: return image.transformed(QTransform().rotate(180, Qt::ZAxis)); case 4: return image.transformed(QTransform().rotate(180, Qt::XAxis)); case 5: return image.transformed(QTransform().rotate(180, Qt::YAxis).rotate(90, Qt::ZAxis)); case 6: return image.transformed(QTransform().rotate(90, Qt::ZAxis)); case 7: return image.transformed(QTransform().rotate(180, Qt::XAxis).rotate(90, Qt::ZAxis)); case 8: return image.transformed(QTransform().rotate(270, Qt::ZAxis)); } } return image; } /*! Sets the image \a thumbnail. */ void QExifImageHeader::setThumbnail (const QImage &thumbnail) { if (!thumbnail.isNull()) { QBuffer buffer; if (buffer.open(QIODevice::WriteOnly) && thumbnail.save(&buffer, "JPG")) { buffer.close(); d->thumbnailSize = thumbnail.size(); d->thumbnailData = buffer.data(); d->thumbnailOrientation = QExifValue(); } } else { d->thumbnailSize = QSize(); d->thumbnailData = QByteArray(); } d->size = -1; } QByteArray QExifImageHeader::extractExif (QIODevice *device) const { QDataStream stream(device); stream.setByteOrder(QDataStream::BigEndian); if (device->read(2) != "\xFF\xD8") return QByteArray(); while (device->read(2) != "\xFF\xE1") { if (device->atEnd()) return QByteArray(); quint16 length; stream >> length; device->seek(device->pos() + length - 2); } quint16 length; stream >> length; if (device->read(4) != "Exif") return QByteArray(); device->read(2); return device->read(length - 8); } QList QExifImageHeader::readIfdHeaders (QDataStream &stream) const { QList headers; quint16 count; stream >> count; for (quint16 i = 0; i < count; i++) { ExifIfdHeader header; stream >> header; headers.append(header); } return headers; } QExifValue QExifImageHeader::readIfdValue (QDataStream &stream, int startPos, const ExifIfdHeader &header) const { switch (header.type) { case QExifValue::Byte: { QVector value(int(header.count)); if (header.count > 4) { stream.device()->seek(startPos + qint64(header.offset)); for (quint32 i = 0; i < header.count; i++) stream >> value[int(i)]; } else { for (quint32 i = 0; i < header.count; i++) value[int(i)] = header.offsetBytes[i]; } return QExifValue(value); } case QExifValue::Undefined: if (header.count > 4) { stream.device()->seek(startPos + qint64(header.offset)); return QExifValue(stream.device()->read(header.count)); } else { return QExifValue(QByteArray::fromRawData(header.offsetAscii, int(header.count))); } case QExifValue::Ascii: if (header.count > 4) { stream.device()->seek(startPos + qint64(header.offset)); QByteArray ascii = stream.device()->read(header.count); return QExifValue(QString::fromUtf8(ascii.constData(), ascii.size() - 1)); } else { return QExifValue(QString::fromUtf8(header.offsetAscii, int(header.count) - 1)); } case QExifValue::Short: { QVector value(int(header.count)); if (header.count > 2) { stream.device()->seek(startPos + qint64(header.offset)); for (quint32 i = 0; i < header.count; i++) stream >> value[int(i)]; } else { for (quint32 i = 0; i < header.count; i++) value[int(i)] = header.offsetShorts[i]; } return QExifValue(value); } case QExifValue::Long: { QVector value(int(header.count)); if (header.count > 1) { stream.device()->seek(startPos + qint64(header.offset)); for (quint32 i = 0; i < header.count; i++) stream >> value[int(i)]; } else if (header.count == 1) { value[0] = header.offset; } return QExifValue(value); } case QExifValue::SignedLong: { QVector value(int(header.count)); if (header.count > 1) { stream.device()->seek(startPos + qint64(header.offset)); for (quint32 i = 0; i < header.count; i++) stream >> value[int(i)]; } else if (header.count == 1) { value[0] = int(header.offset); } return QExifValue(value); } case QExifValue::Rational: { QVector value(int(header.count)); stream.device()->seek(startPos + qint64(header.offset)); for (quint32 i = 0; i < header.count; i++) stream >> value[int(i)]; return QExifValue(value); } case QExifValue::SignedRational: { QVector value(int(header.count)); stream.device()->seek(startPos + qint64(header.offset)); for (quint32 i = 0; i < header.count; i++) stream >> value[int(i)]; return QExifValue(value); } default: qWarning() << "Invalid Ifd Type" << header.type; return QExifValue(); } } template QMap QExifImageHeader::readIfdValues ( QDataStream &stream, int startPos, const QList &headers ) const { QMap values; // This needs to be non-const so it works with gcc3 QList headers_ = headers; foreach(const ExifIfdHeader &header, headers_) values[T(header.tag)] = readIfdValue(stream, startPos, header); return values; } template QMap QExifImageHeader::readIfdValues ( QDataStream &stream, int startPos, const QExifValue &pointer ) const { if (pointer.type() == QExifValue::Long && pointer.count() == 1) { stream.device()->seek(qint64(startPos) + pointer.toLong()); QList headers = readIfdHeaders(stream); return readIfdValues(stream, startPos, headers); } else { return QMap(); } } /*! Reads the contents of an EXIF header from an I/O \a device. Returns true if the header was read and false otherwise. \sa loadFromJpeg(), write() */ bool QExifImageHeader::read (QIODevice *device) { clear(); int startPos = int(device->pos()); QDataStream stream(device); QByteArray byteOrder = device->read(2); if (byteOrder == "II") { d->byteOrder = QSysInfo::LittleEndian; stream.setByteOrder(QDataStream::LittleEndian); } else if (byteOrder == "MM") { d->byteOrder = QSysInfo::BigEndian; stream.setByteOrder(QDataStream::BigEndian); } else { return false; } quint16 id; quint32 offset; stream >> id; stream >> offset; if (id != 0x002A) return false; device->seek(startPos + qint64(offset)); QList headers = readIfdHeaders(stream); stream >> offset; d->imageIfdValues = readIfdValues(stream, startPos, headers); QExifValue exifIfdPointer = d->imageIfdValues.take(ImageTag(ExifIfdPointer)); QExifValue gpsIfdPointer = d->imageIfdValues.take(ImageTag(GpsInfoIfdPointer)); d->exifIfdValues = readIfdValues(stream, startPos, exifIfdPointer); d->gpsIfdValues = readIfdValues(stream, startPos, gpsIfdPointer); d->exifIfdValues.remove(ExifExtendedTag(InteroperabilityIfdPointer)); if (offset) { device->seek(startPos + qint64(offset)); QMap thumbnailIfdValues = readIfdValues( stream, startPos, readIfdHeaders(stream)); QExifValue jpegOffset = thumbnailIfdValues.value(JpegInterchangeFormat); QExifValue jpegLength = thumbnailIfdValues.value(JpegInterchangeFormatLength); if (jpegOffset.type() == QExifValue::Long && jpegOffset.count() == 1 && jpegLength.type() == QExifValue::Long && jpegLength.count() == 1) { device->seek(startPos + qint64(jpegOffset.toLong())); d->thumbnailData = device->read(jpegLength.toLong()); d->thumbnailXResolution = thumbnailIfdValues.value(XResolution); d->thumbnailYResolution = thumbnailIfdValues.value(YResolution); d->thumbnailResolutionUnit = thumbnailIfdValues.value(ResolutionUnit); d->thumbnailOrientation = thumbnailIfdValues.value(Orientation); } } return true; } quint32 QExifImageHeader::writeExifHeader (QDataStream &stream, quint16 tag, const QExifValue &value, quint32 offset) const { stream << tag; stream << quint16(value.type()); stream << quint32(value.count()); switch (value.type()) { case QExifValue::Byte: if (value.count() <= 4) { foreach(quint8 byte, value.toByteVector()) stream << byte; for (int j = value.count(); j < 4; j++) stream << quint8(0); } else { stream << offset; offset += quint32(value.count()); } break; case QExifValue::Undefined: if (value.count() <= 4) { stream.device()->write(value.toByteArray()); if (value.count() < 4) stream.writeRawData("\0\0\0\0", 4 - value.count()); } else { stream << offset; offset += quint32(value.count()); } break; case QExifValue::Ascii: if (value.count() <= 4) { QByteArray bytes = value.toByteArray(); stream.writeRawData(bytes.constData(), value.count()); if (value.count() < 4) stream.writeRawData("\0\0\0\0", 4 - value.count()); } else { stream << offset; offset += quint32(value.count()); } break; case QExifValue::Short: if (value.count() <= 2) { foreach(quint16 shrt, value.toShortVector()) stream << shrt; for (int j = value.count(); j < 2; j++) stream << quint16(0); } else { stream << offset; offset += quint32(value.count()) * quint32(sizeof(quint16)); } break; case QExifValue::Long: if (value.count() == 0) { stream << quint32(0); } else if (value.count() == 1) { stream << value.toLong(); } else { stream << offset; offset += quint32(value.count()) * quint32(sizeof(quint32)); } break; case QExifValue::SignedLong: if (value.count() == 0) { stream << quint32(0); } else if (value.count() == 1) { stream << value.toSignedLong(); } else { stream << offset; offset += quint32(value.count()) * quint32(sizeof(quint32)); } break; case QExifValue::Rational: if (value.count() == 0) { stream << quint32(0); } else { stream << offset; offset += quint32(value.count()) * quint32(sizeof(quint32)) * 2; } break; case QExifValue::SignedRational: if (value.count() == 0) { stream << quint32(0); } else { stream << offset; offset += quint32(value.count()) * quint32(sizeof(quint32)) * 2; } break; default: qWarning() << "Invalid Ifd Type" << value.type(); stream << quint32(0); } return offset; } void QExifImageHeader::writeExifValue (QDataStream &stream, const QExifValue &value) const { switch (value.type()) { case QExifValue::Byte: if (value.count() > 4) foreach(quint8 byte, value.toByteVector()) stream << byte; break; case QExifValue::Undefined: if (value.count() > 4) stream.device()->write(value.toByteArray()); break; case QExifValue::Ascii: if (value.count() > 4) { QByteArray bytes = value.toByteArray(); stream.writeRawData(bytes.constData(), bytes.size() + 1); } break; case QExifValue::Short: if (value.count() > 2) foreach(quint16 shrt, value.toShortVector()) stream << shrt; break; case QExifValue::Long: if (value.count() > 1) foreach(quint32 lng, value.toLongVector()) stream << lng; break; case QExifValue::SignedLong: if (value.count() > 1) foreach(qint32 lng, value.toSignedLongVector()) stream << lng; break; case QExifValue::Rational: if (value.count() > 0) foreach(QExifURational rational, value.toRationalVector()) stream << rational; break; case QExifValue::SignedRational: if (value.count() > 0) foreach(QExifSRational rational, value.toSignedRationalVector()) stream << rational; break; default: qWarning() << "Invalid Ifd Type" << value.type(); break; } } template quint32 QExifImageHeader::writeExifHeaders ( QDataStream &stream, const QMap &values, quint32 offset ) const { offset += quint32(values.count() * 12); for (typename QMap::const_iterator i = values.constBegin(); i != values.constEnd(); i++) offset = writeExifHeader(stream, i.key(), i.value(), offset); return offset; } template void QExifImageHeader::writeExifValues ( QDataStream &stream, const QMap &values ) const { for (typename QMap::const_iterator i = values.constBegin(); i != values.constEnd(); i++) writeExifValue(stream, i.value()); } /*! Writes an EXIF header to an I/O \a device. Returns the total number of bytes written. */ qint64 QExifImageHeader::write (QIODevice *device) const { // #ifndef QT_NO_DEBUG qint64 startPos = device->pos(); // #endif QDataStream stream(device); if (d->byteOrder == QSysInfo::LittleEndian) { stream.setByteOrder(QDataStream::LittleEndian); device->write("II", 2); device->write("\x2A\x00", 2); device->write("\x08\x00\x00\x00", 4); } else if (d->byteOrder == QSysInfo::BigEndian) { stream.setByteOrder(QDataStream::BigEndian); device->write("MM", 2); device->write("\x00\x2A", 2); device->write("\x00\x00\x00\x08", 4); } quint16 count = quint16(d->imageIfdValues.count() + 1); quint32 offset = 26; if (!d->gpsIfdValues.isEmpty()) { count++; offset += 12; } stream << count; offset = writeExifHeaders(stream, d->imageIfdValues, offset); quint32 exifIfdOffset = offset; stream << quint16(ExifIfdPointer); stream << quint16(QExifValue::Long); stream << quint32(1); stream << exifIfdOffset; offset += calculateSize(d->exifIfdValues); quint32 gpsIfdOffset = offset; if (!d->gpsIfdValues.isEmpty()) { stream << quint16(GpsInfoIfdPointer); stream << quint16(QExifValue::Long); stream << quint32(1); stream << gpsIfdOffset; d->imageIfdValues.insert(ImageTag(GpsInfoIfdPointer), QExifValue(offset)); offset += calculateSize(d->gpsIfdValues); } if (!d->thumbnailData.isEmpty()) stream << offset; // Write offset to thumbnail Ifd. else stream << quint32(0); writeExifValues(stream, d->imageIfdValues); Q_ASSERT(startPos + exifIfdOffset == device->pos()); stream << quint16(d->exifIfdValues.count()); writeExifHeaders(stream, d->exifIfdValues, exifIfdOffset); writeExifValues(stream, d->exifIfdValues); Q_ASSERT(startPos + gpsIfdOffset == device->pos()); if (!d->gpsIfdValues.isEmpty()) { stream << quint16(d->gpsIfdValues.count()); writeExifHeaders(stream, d->gpsIfdValues, gpsIfdOffset); writeExifValues(stream, d->gpsIfdValues); } Q_ASSERT(startPos + offset == device->pos()); if (!d->thumbnailData.isEmpty()) { offset += 86; stream << quint16(7); QExifValue xResolution = d->thumbnailXResolution.isNull() ? QExifValue(QExifURational(72, 1)) : d->thumbnailXResolution; QExifValue yResolution = d->thumbnailYResolution.isNull() ? QExifValue(QExifURational(72, 1)) : d->thumbnailYResolution; QExifValue resolutionUnit = d->thumbnailResolutionUnit.isNull() ? QExifValue(quint16(2)) : d->thumbnailResolutionUnit; QExifValue orientation = d->thumbnailOrientation.isNull() ? QExifValue(quint16(0)) : d->thumbnailOrientation; writeExifHeader(stream, Compression, QExifValue(quint16(6)), offset); offset = writeExifHeader(stream, XResolution, xResolution, offset); offset = writeExifHeader(stream, YResolution, yResolution, offset); writeExifHeader(stream, ResolutionUnit, resolutionUnit, offset); writeExifHeader(stream, Orientation, orientation, offset); writeExifHeader(stream, JpegInterchangeFormat, QExifValue(offset), offset); writeExifHeader(stream, JpegInterchangeFormatLength, QExifValue(quint32(d->thumbnailData.size())), offset); writeExifValue(stream, xResolution); writeExifValue(stream, yResolution); Q_ASSERT(startPos + offset == device->pos()); device->write(d->thumbnailData); offset += quint32(d->thumbnailData.size()); } Q_ASSERT(startPos + offset == device->pos()); d->size = offset; return offset; } linphone-desktop-4.2.5/linphone-app/src/utils/QExifImageHeader.hpp000066400000000000000000000227521376717241300251520ustar00rootroot00000000000000/**************************************************************************** ** ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the Qt scene graph research project. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions ** contained in the Technology Preview License Agreement accompanying ** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. ** ** ** ** ** ** ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ // This file was copied from Qt Extended 4.5 #ifndef QEXIFIMAGEHEADER_H_ #define QEXIFIMAGEHEADER_H_ #include #include #include #include #include #include typedef QPair QExifURational; typedef QPair QExifSRational; class QExifValuePrivate; class QExifValue { public: enum Type { Byte = 1, Ascii = 2, Short = 3, Long = 4, Rational = 5, Undefined = 7, SignedLong = 9, SignedRational = 10 }; enum TextEncoding { NoEncoding, AsciiEncoding, JisEncoding, UnicodeEncoding, UndefinedEncoding }; QExifValue (); QExifValue (quint8 value); QExifValue (const QVector &value); QExifValue (const QString &value, TextEncoding encoding = NoEncoding); QExifValue (quint16 value); QExifValue (const QVector &value); QExifValue (quint32 value); QExifValue (const QVector &value); QExifValue (const QExifURational &value); QExifValue (const QVector &value); QExifValue (const QByteArray &value); QExifValue (qint32 value); QExifValue (const QVector &value); QExifValue (const QExifSRational &value); QExifValue (const QVector &value); QExifValue (const QDateTime &value); QExifValue (const QExifValue &other); QExifValue &operator= (const QExifValue &other); ~QExifValue (); bool operator== (const QExifValue &other) const; bool isNull () const; int type () const; int count () const; TextEncoding encoding () const; quint8 toByte () const; QVector toByteVector () const; QString toString () const; quint16 toShort () const; QVector toShortVector () const; quint32 toLong () const; QVector toLongVector () const; QExifURational toRational () const; QVector toRationalVector () const; QByteArray toByteArray () const; qint32 toSignedLong () const; QVector toSignedLongVector () const; QExifSRational toSignedRational () const; QVector toSignedRationalVector () const; QDateTime toDateTime () const; private: QExplicitlySharedDataPointer d; }; struct ExifIfdHeader; class QExifImageHeaderPrivate; class QExifImageHeader { Q_DISABLE_COPY(QExifImageHeader) public: enum ImageTag { ImageWidth = 0x0100, ImageLength = 0x0101, BitsPerSample = 0x0102, Compression = 0x0103, PhotometricInterpretation = 0x0106, Orientation = 0x0112, SamplesPerPixel = 0x0115, PlanarConfiguration = 0x011C, YCbCrSubSampling = 0x0212, XResolution = 0x011A, YResolution = 0x011B, ResolutionUnit = 0x0128, StripOffsets = 0x0111, RowsPerStrip = 0x0116, StripByteCounts = 0x0117, TransferFunction = 0x012D, WhitePoint = 0x013E, PrimaryChromaciticies = 0x013F, YCbCrCoefficients = 0x0211, ReferenceBlackWhite = 0x0214, DateTime = 0x0132, ImageDescription = 0x010E, Make = 0x010F, Model = 0x0110, Software = 0x0131, Artist = 0x013B, Copyright = 0x8298 }; enum ExifExtendedTag { ExifVersion = 0x9000, FlashPixVersion = 0xA000, ColorSpace = 0xA001, ComponentsConfiguration = 0x9101, CompressedBitsPerPixel = 0x9102, PixelXDimension = 0xA002, PixelYDimension = 0xA003, MakerNote = 0x927C, UserComment = 0x9286, RelatedSoundFile = 0xA004, DateTimeOriginal = 0x9003, DateTimeDigitized = 0x9004, SubSecTime = 0x9290, SubSecTimeOriginal = 0x9291, SubSecTimeDigitized = 0x9292, ImageUniqueId = 0xA420, ExposureTime = 0x829A, FNumber = 0x829D, ExposureProgram = 0x8822, SpectralSensitivity = 0x8824, ISOSpeedRatings = 0x8827, Oecf = 0x8828, ShutterSpeedValue = 0x9201, ApertureValue = 0x9202, BrightnessValue = 0x9203, ExposureBiasValue = 0x9204, MaxApertureValue = 0x9205, SubjectDistance = 0x9206, MeteringMode = 0x9207, LightSource = 0x9208, Flash = 0x9209, FocalLength = 0x920A, SubjectArea = 0x9214, FlashEnergy = 0xA20B, SpatialFrequencyResponse = 0xA20C, FocalPlaneXResolution = 0xA20E, FocalPlaneYResolution = 0xA20F, FocalPlaneResolutionUnit = 0xA210, SubjectLocation = 0xA214, ExposureIndex = 0xA215, SensingMethod = 0xA217, FileSource = 0xA300, SceneType = 0xA301, CfaPattern = 0xA302, CustomRendered = 0xA401, ExposureMode = 0xA402, WhiteBalance = 0xA403, DigitalZoomRatio = 0xA404, FocalLengthIn35mmFilm = 0xA405, SceneCaptureType = 0xA406, GainControl = 0xA407, Contrast = 0xA408, Saturation = 0xA409, Sharpness = 0xA40A, DeviceSettingDescription = 0xA40B, SubjectDistanceRange = 0x40C }; enum GpsTag { GpsVersionId = 0x0000, GpsLatitudeRef = 0x0001, GpsLatitude = 0x0002, GpsLongitudeRef = 0x0003, GpsLongitude = 0x0004, GpsAltitudeRef = 0x0005, GpsAltitude = 0x0006, GpsTimeStamp = 0x0007, GpsSatellites = 0x0008, GpsStatus = 0x0009, GpsMeasureMode = 0x000A, GpsDop = 0x000B, GpsSpeedRef = 0x000C, GpsSpeed = 0x000D, GpsTrackRef = 0x000E, GpsTrack = 0x000F, GpsImageDirectionRef = 0x0010, GpsImageDirection = 0x0011, GpsMapDatum = 0x0012, GpsDestLatitudeRef = 0x0013, GpsDestLatitude = 0x0014, GpsDestLongitudeRef = 0x0015, GpsDestLongitude = 0x0016, GpsDestBearingRef = 0x0017, GpsDestBearing = 0x0018, GpsDestDistanceRef = 0x0019, GpsDestDistance = 0x001A, GpsProcessingMethod = 0x001B, GpsAreaInformation = 0x001C, GpsDateStamp = 0x001D, GpsDifferential = 0x001E }; QExifImageHeader (); explicit QExifImageHeader (const QString &fileName); ~QExifImageHeader (); bool loadFromJpeg (const QString &fileName); bool loadFromJpeg (QIODevice *device); bool saveToJpeg (const QString &fileName) const; bool saveToJpeg (QIODevice *device) const; bool read (QIODevice *device); qint64 write (QIODevice *device) const; qint64 size () const; QSysInfo::Endian byteOrder () const; void clear (); QList imageTags () const; QList extendedTags () const; QList gpsTags () const; bool contains (ImageTag tag) const; bool contains (ExifExtendedTag tag) const; bool contains (GpsTag tag) const; void remove (ImageTag tag); void remove (ExifExtendedTag tag); void remove (GpsTag tag); QExifValue value (ImageTag tag) const; QExifValue value (ExifExtendedTag tag) const; QExifValue value (GpsTag tag) const; void setValue (ImageTag tag, const QExifValue &value); void setValue (ExifExtendedTag tag, const QExifValue &value); void setValue (GpsTag tag, const QExifValue &value); QImage thumbnail () const; void setThumbnail (const QImage &thumbnail); private: enum PrivateTag { ExifIfdPointer = 0x8769, GpsInfoIfdPointer = 0x8825, InteroperabilityIfdPointer = 0xA005, JpegInterchangeFormat = 0x0201, JpegInterchangeFormatLength = 0x0202 }; QByteArray extractExif (QIODevice *device) const; QList readIfdHeaders (QDataStream &stream) const; QExifValue readIfdValue (QDataStream &stream, int startPos, const ExifIfdHeader &header) const; template QMap readIfdValues (QDataStream &stream, int startPos, const QList &headers) const; template QMap readIfdValues (QDataStream &stream, int startPos, const QExifValue &pointer) const; quint32 writeExifHeader (QDataStream &stream, quint16 tag, const QExifValue &value, quint32 offset) const; void writeExifValue (QDataStream &stream, const QExifValue &value) const; template quint32 writeExifHeaders (QDataStream &stream, const QMap &values, quint32 offset) const; template void writeExifValues (QDataStream &target, const QMap &values) const; quint32 sizeOf (const QExifValue &value) const; template quint32 calculateSize (const QMap &values) const; QExifImageHeaderPrivate *d; }; #endif // ifndef QEXIFIMAGEHEADER_H_ linphone-desktop-4.2.5/linphone-app/src/utils/Utils.cpp000066400000000000000000001065361376717241300231600ustar00rootroot00000000000000/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include #include #include #include #include #include "Utils.hpp" #include "components/core/CoreManager.hpp" // ============================================================================= namespace { constexpr int SafeFilePathLimit = 100; } char *Utils::rstrstr (const char *a, const char *b) { size_t a_len = strlen(a); size_t b_len = strlen(b); if (b_len > a_len) return nullptr; for (const char *s = a + a_len - b_len; s >= a; --s) { if (!strncmp(s, b, b_len)) return const_cast(s); } return nullptr; } // ----------------------------------------------------------------------------- QImage Utils::getImage(const QString &pUri) { QImage image(pUri); if(image.isNull()){// Try to determine format from headers instead of using suffix QImageReader reader(pUri); reader.setDecideFormatFromContent(true); QByteArray format = reader.format(); if(!format.isEmpty()) image = QImage(pUri, format); } return image; } QString Utils::getSafeFilePath (const QString &filePath, bool *soFarSoGood) { if (soFarSoGood) *soFarSoGood = true; QFileInfo info(filePath); if (!info.exists()) return filePath; const QString prefix = QStringLiteral("%1/%2").arg(info.absolutePath()).arg(info.baseName()); const QString ext = info.completeSuffix(); for (int i = 1; i < SafeFilePathLimit; ++i) { QString safePath = QStringLiteral("%1 (%3).%4").arg(prefix).arg(i).arg(ext); if (!QFileInfo::exists(safePath)) return safePath; } if (soFarSoGood) *soFarSoGood = false; return QString(""); } std::shared_ptr Utils::getMatchingLocalAddress(std::shared_ptr p_localAddress){ QVector > addresses; // Get default proxy addresses.push_back(CoreManager::getInstance()->getCore()->createPrimaryContactParsed()); auto proxyList = CoreManager::getInstance()->getCore()->getProxyConfigList(); foreach(auto proxy, proxyList) addresses.push_back(proxy->getIdentityAddress()->clone()); foreach(auto address, addresses){ if( address->getUsername() == p_localAddress->getUsername() && address->getDomain() == p_localAddress->getDomain()) return address; } return p_localAddress; } // Return at most : sip:username@domain QString Utils::cleanSipAddress (const QString &sipAddress) { std::shared_ptr addr = linphone::Factory::get()->createAddress(Utils::appStringToCoreString(sipAddress)); if( addr) { QStringList fields = Utils::coreStringToAppString(addr->asStringUriOnly()).split('@'); if(fields.size() > 0){// maybe useless but it's just to be sure to have a domain fields.removeLast(); QString domain = Utils::coreStringToAppString(addr->getDomain()); if( domain.count(':')>1) fields.append('['+domain+']'); else fields.append(domain); return fields.join('@'); } } return sipAddress; } // Data to retrieve WIN32 process #ifdef _WIN32 #include struct EnumData { DWORD dwProcessId; HWND hWnd; }; // Application-defined callback for EnumWindows BOOL CALLBACK EnumProc(HWND hWnd, LPARAM lParam) { // Retrieve storage location for communication data EnumData& ed = *(EnumData*)lParam; DWORD dwProcessId = 0x0; // Query process ID for hWnd GetWindowThreadProcessId(hWnd, &dwProcessId); // Apply filter - if you want to implement additional restrictions, // this is the place to do so. if (ed.dwProcessId == dwProcessId) { // Found a window matching the process ID ed.hWnd = hWnd; // Report success SetLastError(ERROR_SUCCESS); // Stop enumeration return FALSE; } // Continue enumeration return TRUE; } // Main entry HWND FindWindowFromProcessId(DWORD dwProcessId) { EnumData ed = { dwProcessId }; if (!EnumWindows(EnumProc, (LPARAM)&ed) && (GetLastError() == ERROR_SUCCESS)) { return ed.hWnd; } return NULL; } // Helper method for convenience HWND FindWindowFromProcess(HANDLE hProcess) { return FindWindowFromProcessId(GetProcessId(hProcess)); } #endif bool Utils::processExists(const quint64& p_processId) { #ifdef _WIN32 return FindWindowFromProcessId(p_processId) != NULL; #else return true; #endif } QString Utils::getCountryName(const QLocale::Country& p_country) { QString countryName; switch(p_country) { case QLocale::Afghanistan: if((countryName = QCoreApplication::translate("country", "Afghanistan"))== "Afghanistan") countryName = "";break; case QLocale::Albania: if((countryName = QCoreApplication::translate("country", "Albania"))== "Albania") countryName = "";break; case QLocale::Algeria: if((countryName = QCoreApplication::translate("country", "Algeria"))== "Algeria") countryName = "";break; case QLocale::AmericanSamoa: if((countryName = QCoreApplication::translate("country", "AmericanSamoa"))== "AmericanSamoa") countryName = "";break; case QLocale::Andorra: if((countryName = QCoreApplication::translate("country", "Andorra"))== "Andorra") countryName = "";break; case QLocale::Angola: if((countryName = QCoreApplication::translate("country", "Angola"))== "Angola") countryName = "";break; case QLocale::Anguilla: if((countryName = QCoreApplication::translate("country", "Anguilla"))== "Anguilla") countryName = "";break; case QLocale::AntiguaAndBarbuda: if((countryName = QCoreApplication::translate("country", "AntiguaAndBarbuda"))== "AntiguaAndBarbuda") countryName = "";break; case QLocale::Argentina: if((countryName = QCoreApplication::translate("country", "Argentina"))== "Argentina") countryName = "";break; case QLocale::Armenia: if((countryName = QCoreApplication::translate("country", "Armenia"))== "Armenia") countryName = "";break; case QLocale::Aruba: if((countryName = QCoreApplication::translate("country", "Aruba"))== "Aruba") countryName = "";break; case QLocale::Australia: if((countryName = QCoreApplication::translate("country", "Australia"))== "Australia") countryName = "";break; case QLocale::Austria: if((countryName = QCoreApplication::translate("country", "Austria"))== "Austria") countryName = "";break; case QLocale::Azerbaijan: if((countryName = QCoreApplication::translate("country", "Azerbaijan"))== "Azerbaijan") countryName = "";break; case QLocale::Bahamas: if((countryName = QCoreApplication::translate("country", "Bahamas"))== "Bahamas") countryName = "";break; case QLocale::Bahrain: if((countryName = QCoreApplication::translate("country", "Bahrain"))== "Bahrain") countryName = "";break; case QLocale::Bangladesh: if((countryName = QCoreApplication::translate("country", "Bangladesh"))== "Bangladesh") countryName = "";break; case QLocale::Barbados: if((countryName = QCoreApplication::translate("country", "Barbados"))== "Barbados") countryName = "";break; case QLocale::Belarus: if((countryName = QCoreApplication::translate("country", "Belarus"))== "Belarus") countryName = "";break; case QLocale::Belgium: if((countryName = QCoreApplication::translate("country", "Belgium"))== "Belgium") countryName = "";break; case QLocale::Belize: if((countryName = QCoreApplication::translate("country", "Belize"))== "Belize") countryName = "";break; case QLocale::Benin: if((countryName = QCoreApplication::translate("country", "Benin"))== "Benin") countryName = "";break; case QLocale::Bermuda: if((countryName = QCoreApplication::translate("country", "Bermuda"))== "Bermuda") countryName = "";break; case QLocale::Bhutan: if((countryName = QCoreApplication::translate("country", "Bhutan"))== "Bhutan") countryName = "";break; case QLocale::Bolivia: if((countryName = QCoreApplication::translate("country", "Bolivia"))== "Bolivia") countryName = "";break; case QLocale::BosniaAndHerzegowina: if((countryName = QCoreApplication::translate("country", "BosniaAndHerzegowina"))== "BosniaAndHerzegowina") countryName = "";break; case QLocale::Botswana: if((countryName = QCoreApplication::translate("country", "Botswana"))== "Botswana") countryName = "";break; case QLocale::Brazil: if((countryName = QCoreApplication::translate("country", "Brazil"))== "Brazil") countryName = "";break; case QLocale::Brunei: if((countryName = QCoreApplication::translate("country", "Brunei"))== "Brunei") countryName = "";break; case QLocale::Bulgaria: if((countryName = QCoreApplication::translate("country", "Bulgaria"))== "Bulgaria") countryName = "";break; case QLocale::BurkinaFaso: if((countryName = QCoreApplication::translate("country", "BurkinaFaso"))== "BurkinaFaso") countryName = "";break; case QLocale::Burundi: if((countryName = QCoreApplication::translate("country", "Burundi"))== "Burundi") countryName = "";break; case QLocale::Cambodia: if((countryName = QCoreApplication::translate("country", "Cambodia"))== "Cambodia") countryName = "";break; case QLocale::Cameroon: if((countryName = QCoreApplication::translate("country", "Cameroon"))== "Cameroon") countryName = "";break; case QLocale::Canada: if((countryName = QCoreApplication::translate("country", "Canada"))== "Canada") countryName = "";break; case QLocale::CapeVerde: if((countryName = QCoreApplication::translate("country", "CapeVerde"))== "CapeVerde") countryName = "";break; case QLocale::CaymanIslands: if((countryName = QCoreApplication::translate("country", "CaymanIslands"))== "CaymanIslands") countryName = "";break; case QLocale::CentralAfricanRepublic: if((countryName = QCoreApplication::translate("country", "CentralAfricanRepublic"))== "CentralAfricanRepublic") countryName = "";break; case QLocale::Chad: if((countryName = QCoreApplication::translate("country", "Chad"))== "Chad") countryName = "";break; case QLocale::Chile: if((countryName = QCoreApplication::translate("country", "Chile"))== "Chile") countryName = "";break; case QLocale::China: if((countryName = QCoreApplication::translate("country", "China"))== "China") countryName = "";break; case QLocale::Colombia: if((countryName = QCoreApplication::translate("country", "Colombia"))== "Colombia") countryName = "";break; case QLocale::Comoros: if((countryName = QCoreApplication::translate("country", "Comoros"))== "Comoros") countryName = "";break; case QLocale::PeoplesRepublicOfCongo: if((countryName = QCoreApplication::translate("country", "PeoplesRepublicOfCongo"))== "PeoplesRepublicOfCongo") countryName = "";break; case QLocale::DemocraticRepublicOfCongo: if((countryName = QCoreApplication::translate("country", "DemocraticRepublicOfCongo"))== "DemocraticRepublicOfCongo") countryName = "";break; case QLocale::CookIslands: if((countryName = QCoreApplication::translate("country", "CookIslands"))== "CookIslands") countryName = "";break; case QLocale::CostaRica: if((countryName = QCoreApplication::translate("country", "CostaRica"))== "CostaRica") countryName = "";break; case QLocale::IvoryCoast: if((countryName = QCoreApplication::translate("country", "IvoryCoast"))== "IvoryCoast") countryName = "";break; case QLocale::Croatia: if((countryName = QCoreApplication::translate("country", "Croatia"))== "Croatia") countryName = "";break; case QLocale::Cuba: if((countryName = QCoreApplication::translate("country", "Cuba"))== "Cuba") countryName = "";break; case QLocale::Cyprus: if((countryName = QCoreApplication::translate("country", "Cyprus"))== "Cyprus") countryName = "";break; case QLocale::CzechRepublic: if((countryName = QCoreApplication::translate("country", "CzechRepublic"))== "CzechRepublic") countryName = "";break; case QLocale::Denmark: if((countryName = QCoreApplication::translate("country", "Denmark"))== "Denmark") countryName = "";break; case QLocale::Djibouti: if((countryName = QCoreApplication::translate("country", "Djibouti"))== "Djibouti") countryName = "";break; case QLocale::Dominica: if((countryName = QCoreApplication::translate("country", "Dominica"))== "Dominica") countryName = "";break; case QLocale::DominicanRepublic: if((countryName = QCoreApplication::translate("country", "DominicanRepublic"))== "DominicanRepublic") countryName = "";break; case QLocale::Ecuador: if((countryName = QCoreApplication::translate("country", "Ecuador"))== "Ecuador") countryName = "";break; case QLocale::Egypt: if((countryName = QCoreApplication::translate("country", "Egypt"))== "Egypt") countryName = "";break; case QLocale::ElSalvador: if((countryName = QCoreApplication::translate("country", "ElSalvador"))== "ElSalvador") countryName = "";break; case QLocale::EquatorialGuinea: if((countryName = QCoreApplication::translate("country", "EquatorialGuinea"))== "EquatorialGuinea") countryName = "";break; case QLocale::Eritrea: if((countryName = QCoreApplication::translate("country", "Eritrea"))== "Eritrea") countryName = "";break; case QLocale::Estonia: if((countryName = QCoreApplication::translate("country", "Estonia"))== "Estonia") countryName = "";break; case QLocale::Ethiopia: if((countryName = QCoreApplication::translate("country", "Ethiopia"))== "Ethiopia") countryName = "";break; case QLocale::FalklandIslands: if((countryName = QCoreApplication::translate("country", "FalklandIslands"))== "FalklandIslands") countryName = "";break; case QLocale::FaroeIslands: if((countryName = QCoreApplication::translate("country", "FaroeIslands"))== "FaroeIslands") countryName = "";break; case QLocale::Fiji: if((countryName = QCoreApplication::translate("country", "Fiji"))== "Fiji") countryName = "";break; case QLocale::Finland: if((countryName = QCoreApplication::translate("country", "Finland"))== "Finland") countryName = "";break; case QLocale::France: if((countryName = QCoreApplication::translate("country", "France"))== "France") countryName = "";break; case QLocale::FrenchGuiana: if((countryName = QCoreApplication::translate("country", "FrenchGuiana"))== "FrenchGuiana") countryName = "";break; case QLocale::FrenchPolynesia: if((countryName = QCoreApplication::translate("country", "FrenchPolynesia"))== "FrenchPolynesia") countryName = "";break; case QLocale::Gabon: if((countryName = QCoreApplication::translate("country", "Gabon"))== "Gabon") countryName = "";break; case QLocale::Gambia: if((countryName = QCoreApplication::translate("country", "Gambia"))== "Gambia") countryName = "";break; case QLocale::Georgia: if((countryName = QCoreApplication::translate("country", "Georgia"))== "Georgia") countryName = "";break; case QLocale::Germany: if((countryName = QCoreApplication::translate("country", "Germany"))== "Germany") countryName = "";break; case QLocale::Ghana: if((countryName = QCoreApplication::translate("country", "Ghana"))== "Ghana") countryName = "";break; case QLocale::Gibraltar: if((countryName = QCoreApplication::translate("country", "Gibraltar"))== "Gibraltar") countryName = "";break; case QLocale::Greece: if((countryName = QCoreApplication::translate("country", "Greece"))== "Greece") countryName = "";break; case QLocale::Greenland: if((countryName = QCoreApplication::translate("country", "Greenland"))== "Greenland") countryName = "";break; case QLocale::Grenada: if((countryName = QCoreApplication::translate("country", "Grenada"))== "Grenada") countryName = "";break; case QLocale::Guadeloupe: if((countryName = QCoreApplication::translate("country", "Guadeloupe"))== "Guadeloupe") countryName = "";break; case QLocale::Guam: if((countryName = QCoreApplication::translate("country", "Guam"))== "Guam") countryName = "";break; case QLocale::Guatemala: if((countryName = QCoreApplication::translate("country", "Guatemala"))== "Guatemala") countryName = "";break; case QLocale::Guinea: if((countryName = QCoreApplication::translate("country", "Guinea"))== "Guinea") countryName = "";break; case QLocale::GuineaBissau: if((countryName = QCoreApplication::translate("country", "GuineaBissau"))== "GuineaBissau") countryName = "";break; case QLocale::Guyana: if((countryName = QCoreApplication::translate("country", "Guyana"))== "Guyana") countryName = "";break; case QLocale::Haiti: if((countryName = QCoreApplication::translate("country", "Haiti"))== "Haiti") countryName = "";break; case QLocale::Honduras: if((countryName = QCoreApplication::translate("country", "Honduras"))== "Honduras") countryName = "";break; case QLocale::HongKong: if((countryName = QCoreApplication::translate("country", "HongKong"))== "HongKong") countryName = "";break; case QLocale::Hungary: if((countryName = QCoreApplication::translate("country", "Hungary"))== "Hungary") countryName = "";break; case QLocale::Iceland: if((countryName = QCoreApplication::translate("country", "Iceland"))== "Iceland") countryName = "";break; case QLocale::India: if((countryName = QCoreApplication::translate("country", "India"))== "India") countryName = "";break; case QLocale::Indonesia: if((countryName = QCoreApplication::translate("country", "Indonesia"))== "Indonesia") countryName = "";break; case QLocale::Iran: if((countryName = QCoreApplication::translate("country", "Iran"))== "Iran") countryName = "";break; case QLocale::Iraq: if((countryName = QCoreApplication::translate("country", "Iraq"))== "Iraq") countryName = "";break; case QLocale::Ireland: if((countryName = QCoreApplication::translate("country", "Ireland"))== "Ireland") countryName = "";break; case QLocale::Israel: if((countryName = QCoreApplication::translate("country", "Israel"))== "Israel") countryName = "";break; case QLocale::Italy: if((countryName = QCoreApplication::translate("country", "Italy"))== "Italy") countryName = "";break; case QLocale::Jamaica: if((countryName = QCoreApplication::translate("country", "Jamaica"))== "Jamaica") countryName = "";break; case QLocale::Japan: if((countryName = QCoreApplication::translate("country", "Japan"))== "Japan") countryName = "";break; case QLocale::Jordan: if((countryName = QCoreApplication::translate("country", "Jordan"))== "Jordan") countryName = "";break; case QLocale::Kazakhstan: if((countryName = QCoreApplication::translate("country", "Kazakhstan"))== "Kazakhstan") countryName = "";break; case QLocale::Kenya: if((countryName = QCoreApplication::translate("country", "Kenya"))== "Kenya") countryName = "";break; case QLocale::Kiribati: if((countryName = QCoreApplication::translate("country", "Kiribati"))== "Kiribati") countryName = "";break; case QLocale::DemocraticRepublicOfKorea: if((countryName = QCoreApplication::translate("country", "DemocraticRepublicOfKorea"))== "DemocraticRepublicOfKorea") countryName = "";break; case QLocale::RepublicOfKorea: if((countryName = QCoreApplication::translate("country", "RepublicOfKorea"))== "RepublicOfKorea") countryName = "";break; case QLocale::Kuwait: if((countryName = QCoreApplication::translate("country", "Kuwait"))== "Kuwait") countryName = "";break; case QLocale::Kyrgyzstan: if((countryName = QCoreApplication::translate("country", "Kyrgyzstan"))== "Kyrgyzstan") countryName = "";break; case QLocale::Laos: if((countryName = QCoreApplication::translate("country", "Laos"))== "Laos") countryName = "";break; case QLocale::Latvia: if((countryName = QCoreApplication::translate("country", "Latvia"))== "Latvia") countryName = "";break; case QLocale::Lebanon: if((countryName = QCoreApplication::translate("country", "Lebanon"))== "Lebanon") countryName = "";break; case QLocale::Lesotho: if((countryName = QCoreApplication::translate("country", "Lesotho"))== "Lesotho") countryName = "";break; case QLocale::Liberia: if((countryName = QCoreApplication::translate("country", "Liberia"))== "Liberia") countryName = "";break; case QLocale::Libya: if((countryName = QCoreApplication::translate("country", "Libya"))== "Libya") countryName = "";break; case QLocale::Liechtenstein: if((countryName = QCoreApplication::translate("country", "Liechtenstein"))== "Liechtenstein") countryName = "";break; case QLocale::Lithuania: if((countryName = QCoreApplication::translate("country", "Lithuania"))== "Lithuania") countryName = "";break; case QLocale::Luxembourg: if((countryName = QCoreApplication::translate("country", "Luxembourg"))== "Luxembourg") countryName = "";break; case QLocale::Macau: if((countryName = QCoreApplication::translate("country", "Macau"))== "Macau") countryName = "";break; case QLocale::Macedonia: if((countryName = QCoreApplication::translate("country", "Macedonia"))== "Macedonia") countryName = "";break; case QLocale::Madagascar: if((countryName = QCoreApplication::translate("country", "Madagascar"))== "Madagascar") countryName = "";break; case QLocale::Malawi: if((countryName = QCoreApplication::translate("country", "Malawi"))== "Malawi") countryName = "";break; case QLocale::Malaysia: if((countryName = QCoreApplication::translate("country", "Malaysia"))== "Malaysia") countryName = "";break; case QLocale::Maldives: if((countryName = QCoreApplication::translate("country", "Maldives"))== "Maldives") countryName = "";break; case QLocale::Mali: if((countryName = QCoreApplication::translate("country", "Mali"))== "Mali") countryName = "";break; case QLocale::Malta: if((countryName = QCoreApplication::translate("country", "Malta"))== "Malta") countryName = "";break; case QLocale::MarshallIslands: if((countryName = QCoreApplication::translate("country", "MarshallIslands"))== "MarshallIslands") countryName = "";break; case QLocale::Martinique: if((countryName = QCoreApplication::translate("country", "Martinique"))== "Martinique") countryName = "";break; case QLocale::Mauritania: if((countryName = QCoreApplication::translate("country", "Mauritania"))== "Mauritania") countryName = "";break; case QLocale::Mauritius: if((countryName = QCoreApplication::translate("country", "Mauritius"))== "Mauritius") countryName = "";break; case QLocale::Mayotte: if((countryName = QCoreApplication::translate("country", "Mayotte"))== "Mayotte") countryName = "";break; case QLocale::Mexico: if((countryName = QCoreApplication::translate("country", "Mexico"))== "Mexico") countryName = "";break; case QLocale::Micronesia: if((countryName = QCoreApplication::translate("country", "Micronesia"))== "Micronesia") countryName = "";break; case QLocale::Moldova: if((countryName = QCoreApplication::translate("country", "Moldova"))== "Moldova") countryName = "";break; case QLocale::Monaco: if((countryName = QCoreApplication::translate("country", "Monaco"))== "Monaco") countryName = "";break; case QLocale::Mongolia: if((countryName = QCoreApplication::translate("country", "Mongolia"))== "Mongolia") countryName = "";break; case QLocale::Montenegro: if((countryName = QCoreApplication::translate("country", "Montenegro"))== "Montenegro") countryName = "";break; case QLocale::Montserrat: if((countryName = QCoreApplication::translate("country", "Montserrat"))== "Montserrat") countryName = "";break; case QLocale::Morocco: if((countryName = QCoreApplication::translate("country", "Morocco"))== "Morocco") countryName = "";break; case QLocale::Mozambique: if((countryName = QCoreApplication::translate("country", "Mozambique"))== "Mozambique") countryName = "";break; case QLocale::Myanmar: if((countryName = QCoreApplication::translate("country", "Myanmar"))== "Myanmar") countryName = "";break; case QLocale::Namibia: if((countryName = QCoreApplication::translate("country", "Namibia"))== "Namibia") countryName = "";break; case QLocale::NauruCountry: if((countryName = QCoreApplication::translate("country", "NauruCountry"))== "NauruCountry") countryName = "";break; case QLocale::Nepal: if((countryName = QCoreApplication::translate("country", "Nepal"))== "Nepal") countryName = "";break; case QLocale::Netherlands: if((countryName = QCoreApplication::translate("country", "Netherlands"))== "Netherlands") countryName = "";break; case QLocale::NewCaledonia: if((countryName = QCoreApplication::translate("country", "NewCaledonia"))== "NewCaledonia") countryName = "";break; case QLocale::NewZealand: if((countryName = QCoreApplication::translate("country", "NewZealand"))== "NewZealand") countryName = "";break; case QLocale::Nicaragua: if((countryName = QCoreApplication::translate("country", "Nicaragua"))== "Nicaragua") countryName = "";break; case QLocale::Niger: if((countryName = QCoreApplication::translate("country", "Niger"))== "Niger") countryName = "";break; case QLocale::Nigeria: if((countryName = QCoreApplication::translate("country", "Nigeria"))== "Nigeria") countryName = "";break; case QLocale::Niue: if((countryName = QCoreApplication::translate("country", "Niue"))== "Niue") countryName = "";break; case QLocale::NorfolkIsland: if((countryName = QCoreApplication::translate("country", "NorfolkIsland"))== "NorfolkIsland") countryName = "";break; case QLocale::NorthernMarianaIslands: if((countryName = QCoreApplication::translate("country", "NorthernMarianaIslands"))== "NorthernMarianaIslands") countryName = "";break; case QLocale::Norway: if((countryName = QCoreApplication::translate("country", "Norway"))== "Norway") countryName = "";break; case QLocale::Oman: if((countryName = QCoreApplication::translate("country", "Oman"))== "Oman") countryName = "";break; case QLocale::Pakistan: if((countryName = QCoreApplication::translate("country", "Pakistan"))== "Pakistan") countryName = "";break; case QLocale::Palau: if((countryName = QCoreApplication::translate("country", "Palau"))== "Palau") countryName = "";break; case QLocale::PalestinianTerritories: if((countryName = QCoreApplication::translate("country", "PalestinianTerritories"))== "PalestinianTerritories") countryName = "";break; case QLocale::Panama: if((countryName = QCoreApplication::translate("country", "Panama"))== "Panama") countryName = "";break; case QLocale::PapuaNewGuinea: if((countryName = QCoreApplication::translate("country", "PapuaNewGuinea"))== "PapuaNewGuinea") countryName = "";break; case QLocale::Paraguay: if((countryName = QCoreApplication::translate("country", "Paraguay"))== "Paraguay") countryName = "";break; case QLocale::Peru: if((countryName = QCoreApplication::translate("country", "Peru"))== "Peru") countryName = "";break; case QLocale::Philippines: if((countryName = QCoreApplication::translate("country", "Philippines"))== "Philippines") countryName = "";break; case QLocale::Poland: if((countryName = QCoreApplication::translate("country", "Poland"))== "Poland") countryName = "";break; case QLocale::Portugal: if((countryName = QCoreApplication::translate("country", "Portugal"))== "Portugal") countryName = "";break; case QLocale::PuertoRico: if((countryName = QCoreApplication::translate("country", "PuertoRico"))== "PuertoRico") countryName = "";break; case QLocale::Qatar: if((countryName = QCoreApplication::translate("country", "Qatar"))== "Qatar") countryName = "";break; case QLocale::Reunion: if((countryName = QCoreApplication::translate("country", "Reunion"))== "Reunion") countryName = "";break; case QLocale::Romania: if((countryName = QCoreApplication::translate("country", "Romania"))== "Romania") countryName = "";break; case QLocale::RussianFederation: if((countryName = QCoreApplication::translate("country", "RussianFederation"))== "RussianFederation") countryName = "";break; case QLocale::Rwanda: if((countryName = QCoreApplication::translate("country", "Rwanda"))== "Rwanda") countryName = "";break; case QLocale::SaintHelena: if((countryName = QCoreApplication::translate("country", "SaintHelena"))== "SaintHelena") countryName = "";break; case QLocale::SaintKittsAndNevis: if((countryName = QCoreApplication::translate("country", "SaintKittsAndNevis"))== "SaintKittsAndNevis") countryName = "";break; case QLocale::SaintLucia: if((countryName = QCoreApplication::translate("country", "SaintLucia"))== "SaintLucia") countryName = "";break; case QLocale::SaintPierreAndMiquelon: if((countryName = QCoreApplication::translate("country", "SaintPierreAndMiquelon"))== "SaintPierreAndMiquelon") countryName = "";break; case QLocale::SaintVincentAndTheGrenadines: if((countryName = QCoreApplication::translate("country", "SaintVincentAndTheGrenadines"))== "SaintVincentAndTheGrenadines") countryName = "";break; case QLocale::Samoa: if((countryName = QCoreApplication::translate("country", "Samoa"))== "Samoa") countryName = "";break; case QLocale::SanMarino: if((countryName = QCoreApplication::translate("country", "SanMarino"))== "SanMarino") countryName = "";break; case QLocale::SaoTomeAndPrincipe: if((countryName = QCoreApplication::translate("country", "SaoTomeAndPrincipe"))== "SaoTomeAndPrincipe") countryName = "";break; case QLocale::SaudiArabia: if((countryName = QCoreApplication::translate("country", "SaudiArabia"))== "SaudiArabia") countryName = "";break; case QLocale::Senegal: if((countryName = QCoreApplication::translate("country", "Senegal"))== "Senegal") countryName = "";break; case QLocale::Serbia: if((countryName = QCoreApplication::translate("country", "Serbia"))== "Serbia") countryName = "";break; case QLocale::Seychelles: if((countryName = QCoreApplication::translate("country", "Seychelles"))== "Seychelles") countryName = "";break; case QLocale::SierraLeone: if((countryName = QCoreApplication::translate("country", "SierraLeone"))== "SierraLeone") countryName = "";break; case QLocale::Singapore: if((countryName = QCoreApplication::translate("country", "Singapore"))== "Singapore") countryName = "";break; case QLocale::Slovakia: if((countryName = QCoreApplication::translate("country", "Slovakia"))== "Slovakia") countryName = "";break; case QLocale::Slovenia: if((countryName = QCoreApplication::translate("country", "Slovenia"))== "Slovenia") countryName = "";break; case QLocale::SolomonIslands: if((countryName = QCoreApplication::translate("country", "SolomonIslands"))== "SolomonIslands") countryName = "";break; case QLocale::Somalia: if((countryName = QCoreApplication::translate("country", "Somalia"))== "Somalia") countryName = "";break; case QLocale::SouthAfrica: if((countryName = QCoreApplication::translate("country", "SouthAfrica"))== "SouthAfrica") countryName = "";break; case QLocale::Spain: if((countryName = QCoreApplication::translate("country", "Spain"))== "Spain") countryName = "";break; case QLocale::SriLanka: if((countryName = QCoreApplication::translate("country", "SriLanka"))== "SriLanka") countryName = "";break; case QLocale::Sudan: if((countryName = QCoreApplication::translate("country", "Sudan"))== "Sudan") countryName = "";break; case QLocale::Suriname: if((countryName = QCoreApplication::translate("country", "Suriname"))== "Suriname") countryName = "";break; case QLocale::Swaziland: if((countryName = QCoreApplication::translate("country", "Swaziland"))== "Swaziland") countryName = "";break; case QLocale::Sweden: if((countryName = QCoreApplication::translate("country", "Sweden"))== "Sweden") countryName = "";break; case QLocale::Switzerland: if((countryName = QCoreApplication::translate("country", "Switzerland"))== "Switzerland") countryName = "";break; case QLocale::Syria: if((countryName = QCoreApplication::translate("country", "Syria"))== "Syria") countryName = "";break; case QLocale::Taiwan: if((countryName = QCoreApplication::translate("country", "Taiwan"))== "Taiwan") countryName = "";break; case QLocale::Tajikistan: if((countryName = QCoreApplication::translate("country", "Tajikistan"))== "Tajikistan") countryName = "";break; case QLocale::Tanzania: if((countryName = QCoreApplication::translate("country", "Tanzania"))== "Tanzania") countryName = "";break; case QLocale::Thailand: if((countryName = QCoreApplication::translate("country", "Thailand"))== "Thailand") countryName = "";break; case QLocale::Togo: if((countryName = QCoreApplication::translate("country", "Togo"))== "Togo") countryName = "";break; case QLocale::Tokelau: if((countryName = QCoreApplication::translate("country", "Tokelau"))== "Tokelau") countryName = "";break; case QLocale::Tonga: if((countryName = QCoreApplication::translate("country", "Tonga"))== "Tonga") countryName = "";break; case QLocale::TrinidadAndTobago: if((countryName = QCoreApplication::translate("country", "TrinidadAndTobago"))== "TrinidadAndTobago") countryName = "";break; case QLocale::Tunisia: if((countryName = QCoreApplication::translate("country", "Tunisia"))== "Tunisia") countryName = "";break; case QLocale::Turkey: if((countryName = QCoreApplication::translate("country", "Turkey"))== "Turkey") countryName = "";break; case QLocale::Turkmenistan: if((countryName = QCoreApplication::translate("country", "Turkmenistan"))== "Turkmenistan") countryName = "";break; case QLocale::TurksAndCaicosIslands: if((countryName = QCoreApplication::translate("country", "TurksAndCaicosIslands"))== "TurksAndCaicosIslands") countryName = "";break; case QLocale::Tuvalu: if((countryName = QCoreApplication::translate("country", "Tuvalu"))== "Tuvalu") countryName = "";break; case QLocale::Uganda: if((countryName = QCoreApplication::translate("country", "Uganda"))== "Uganda") countryName = "";break; case QLocale::Ukraine: if((countryName = QCoreApplication::translate("country", "Ukraine"))== "Ukraine") countryName = "";break; case QLocale::UnitedArabEmirates: if((countryName = QCoreApplication::translate("country", "UnitedArabEmirates"))== "UnitedArabEmirates") countryName = "";break; case QLocale::UnitedKingdom: if((countryName = QCoreApplication::translate("country", "UnitedKingdom"))== "UnitedKingdom") countryName = "";break; case QLocale::UnitedStates: if((countryName = QCoreApplication::translate("country", "UnitedStates"))== "UnitedStates") countryName = "";break; case QLocale::Uruguay: if((countryName = QCoreApplication::translate("country", "Uruguay"))== "Uruguay") countryName = "";break; case QLocale::Uzbekistan: if((countryName = QCoreApplication::translate("country", "Uzbekistan"))== "Uzbekistan") countryName = "";break; case QLocale::Vanuatu: if((countryName = QCoreApplication::translate("country", "Vanuatu"))== "Vanuatu") countryName = "";break; case QLocale::Venezuela: if((countryName = QCoreApplication::translate("country", "Venezuela"))== "Venezuela") countryName = "";break; case QLocale::Vietnam: if((countryName = QCoreApplication::translate("country", "Vietnam"))== "Vietnam") countryName = "";break; case QLocale::WallisAndFutunaIslands: if((countryName = QCoreApplication::translate("country", "WallisAndFutunaIslands"))== "WallisAndFutunaIslands") countryName = "";break; case QLocale::Yemen: if((countryName = QCoreApplication::translate("country", "Yemen"))== "Yemen") countryName = "";break; case QLocale::Zambia: if((countryName = QCoreApplication::translate("country", "Zambia"))== "Zambia") countryName = "";break; case QLocale::Zimbabwe: if((countryName = QCoreApplication::translate("country", "Zimbabwe"))== "Zimbabwe") countryName = "";break; default: { countryName = QLocale::countryToString(p_country); } } if( countryName == "") countryName = QLocale::countryToString(p_country); return countryName; } // Copy a folder recursively without erasing old file void Utils::copyDir(QString from, QString to) { QDir dir; dir.setPath(from); from += QDir::separator(); to += QDir::separator(); foreach (QString copyFile, dir.entryList(QDir::Files)) {// Copy each files QString toFile = to + copyFile; if (!QFile::exists(toFile)) QFile::copy(from+copyFile, toFile); } foreach (QString nextDir, dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot)) {// Copy folder QString toDir = to + nextDir; QDir().mkpath(toDir);// no need to check if dir exists copyDir(from + nextDir, toDir);//Go up } } linphone-desktop-4.2.5/linphone-app/src/utils/Utils.hpp000066400000000000000000000073161376717241300231610ustar00rootroot00000000000000/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef UTILS_H_ #define UTILS_H_ #include #include #include #include #include // ============================================================================= /* * Define telling g++ that a 'break' statement has been deliberately omitted * in switch block. */ #ifndef UTILS_NO_BREAK #if defined(__GNUC__) && __GNUC__ >= 7 #define UTILS_NO_BREAK __attribute__((fallthrough)) #else #define UTILS_NO_BREAK #endif // if defined(__GNUC__) && __GNUC__ >= 7 #endif // ifndef UTILS_NO_BREAK namespace Utils { inline QString coreStringToAppString (const std::string &str) { return QString::fromLocal8Bit(str.c_str(), int(str.size())); } inline std::string appStringToCoreString (const QString &str) { return qPrintable(str); } // Reverse function of strstr. char *rstrstr (const char *a, const char *b); // Return the path if it is an image else an empty path. QImage getImage(const QString &pUri); // Returns the same path given in parameter if `filePath` exists. // Otherwise returns a safe path with a unique number before the extension. QString getSafeFilePath (const QString &filePath, bool *soFarSoGood = nullptr); std::shared_ptr getMatchingLocalAddress(std::shared_ptr p_localAddress); QString cleanSipAddress (const QString &sipAddress);// Return at most : sip:username@domain // Test if the process exists bool processExists(const quint64& p_processId); // Connect once to a member function. template static inline QMetaObject::Connection connectOnce ( typename QtPrivate::FunctionPointer::Object *sender, Func1 signal, typename QtPrivate::FunctionPointer::Object *receiver, Func2 slot ) { QMetaObject::Connection connection = QObject::connect(sender, signal, receiver, slot); QMetaObject::Connection *deleter = new QMetaObject::Connection(); *deleter = QObject::connect(sender, signal, [connection, deleter] { QObject::disconnect(connection); QObject::disconnect(*deleter); delete deleter; }); return connection; } // Connect once to a function. template static inline QMetaObject::Connection connectOnce ( typename QtPrivate::FunctionPointer::Object *sender, Func1 signal, const QObject *receiver, Func2 slot ) { QMetaObject::Connection connection = QObject::connect(sender, signal, receiver, slot); QMetaObject::Connection *deleter = new QMetaObject::Connection(); *deleter = QObject::connect(sender, signal, [connection, deleter] { QObject::disconnect(connection); QObject::disconnect(*deleter); delete deleter; }); return connection; } QString getCountryName(const QLocale::Country& country); void copyDir(QString from, QString to);// Copy a folder recursively without erasing old file } #endif // UTILS_H_ linphone-desktop-4.2.5/linphone-app/tools/000077500000000000000000000000001376717241300205525ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/tools/create_appimage.sh000077500000000000000000000102561376717241300242230ustar00rootroot00000000000000#!/bin/bash ## ## Copyright (c) 2010-2020 Belledonne Communications SARL. ## ## This file is part of linphone-desktop ## (see https://www.linphone.org). ## ## This program is free software: you can redistribute it and/or modify ## it under the terms of the GNU General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## This program is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU General Public License for more details. ## ## You should have received a copy of the GNU General Public License ## along with this program. If not, see . ## # Arguments : # $1 = Output Filename # $2 = Key of the code sign (optional but mendatory if code signing) # $3 = Passphrase of the code sign (Optional) APP_NAME="linphone" BIN_SOURCE_DIR="OUTPUT/" WORK_DIR="WORK/Packages/AppImageDir" rm -rf ${WORK_DIR}/AppDir mkdir -p "${WORK_DIR}/AppDir/usr/" #Copy all files from the output project cp -rf "${BIN_SOURCE_DIR}"/* "${WORK_DIR}/AppDir/usr/" #remove Packages folder : it is not part of the project rm -rf "${WORK_DIR}/AppDir/usr/Packages" #remove libraries : there are automatically found by linuxdeploy rm -rf "${WORK_DIR}/AppDir/usr/lib" rm -rf "${WORK_DIR}/AppDir/usr/lib64" #Copy soci sqlite3 backend mkdir -p "${WORK_DIR}/AppDir/usr/lib" cp -f "${BIN_SOURCE_DIR}/lib"/libsoci_sqlite3* "${WORK_DIR}/AppDir/usr/lib/" if [ -d "${BIN_SOURCE_DIR}/lib64/mediastreamer" ]; then mkdir -p "${WORK_DIR}/AppDir/usr/plugins/" cp -rf "${BIN_SOURCE_DIR}"/lib64/mediastreamer "${WORK_DIR}/AppDir/usr/plugins/" fi if [ -d "${BIN_SOURCE_DIR}/lib/mediastreamer" ]; then mkdir -p "${WORK_DIR}/AppDir/usr/plugins/" cp -rf "${BIN_SOURCE_DIR}"/lib/mediastreamer "${WORK_DIR}/AppDir/usr/plugins/" fi if [ -f "${WORK_DIR}/AppBin/linuxdeploy-x86_64.AppImage" ]; then echo "linuxdeploy-x86_64.AppImage exists" else wget -P "${WORK_DIR}/AppBin" https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-x86_64.AppImage chmod +x "${WORK_DIR}/AppBin/linuxdeploy-x86_64.AppImage" fi if [ -f "${WORK_DIR}/AppBin/linuxdeploy-plugin-qt-x86_64.AppImage" ]; then echo "linuxdeploy-plugin-qt-x86_64.AppImage exists" else wget -P "${WORK_DIR}/AppBin" https://github.com/linuxdeploy/linuxdeploy-plugin-qt/releases/download/continuous/linuxdeploy-plugin-qt-x86_64.AppImage chmod +x "${WORK_DIR}/AppBin/linuxdeploy-plugin-qt-x86_64.AppImage" fi export QML_SOURCES_PATHS=${QML_SOURCES_PATHS}:${WORK_DIR}/.. echo "-- Generating AppDir for AppImage" if [ -z "$2" ]; then ./${WORK_DIR}/AppBin/linuxdeploy-x86_64.AppImage --appdir=${WORK_DIR}/AppDir -e ${WORK_DIR}/AppDir/usr/bin/linphone --output appimage --desktop-file=${WORK_DIR}/AppDir/usr/share/applications/linphone.desktop -i ${WORK_DIR}/AppDir/usr/share/icons/hicolor/scalable/apps/linphone.svg --plugin qt else if [ -f "${WORK_DIR}/AppBin/appimagetool-x86_64.AppImage" ]; then echo "appimagetool-x86_64.AppImage exists" else wget -P "${WORK_DIR}/AppBin" https://github.com/AppImage/AppImageKit/releases/download/continuous/appimagetool-x86_64.AppImage chmod +x "${WORK_DIR}/AppBin/appimagetool-x86_64.AppImage" fi ./${WORK_DIR}/AppBin/linuxdeploy-x86_64.AppImage --appdir=${WORK_DIR}/AppDir -e ${WORK_DIR}/AppDir/usr/bin/linphone --desktop-file=${WORK_DIR}/AppDir/usr/share/applications/linphone.desktop -i ${WORK_DIR}/AppDir/usr/share/icons/hicolor/scalable/apps/linphone.svg --plugin qt #./linuxdeploy-x86_64.AppImage --appdir=${WORK_DIR}/ -e ${WORK_DIR}/app/bin/linphone --output appimage --desktop-file=${WORK_DIR}/app/share/applications/linphone.desktop -i ${WORK_DIR}/app/share/icons/hicolor/scalable/apps/linphone.svg echo "-- Code Signing of AppImage" if [ -z "$3" ]; then ./${WORK_DIR}/AppBin/appimagetool-x86_64.AppImage ${WORK_DIR}/AppDir --sign --sign-key $2 else ./${WORK_DIR}/AppBin/appimagetool-x86_64.AppImage ${WORK_DIR}/AppDir --sign --sign-key $2 --sign-args "--pinentry-mode loopback --passphrase $3" fi fi mkdir -p "${BIN_SOURCE_DIR}/Packages" mv Linphone*.AppImage "${BIN_SOURCE_DIR}/Packages/$1.AppImage" linphone-desktop-4.2.5/linphone-app/tools/sign_package.bat000066400000000000000000000001071376717241300236530ustar00rootroot00000000000000set /p passphrase=<%1 %2 sign /f %3 /fd SHA256 /p %passphrase% /t %4 %5linphone-desktop-4.2.5/linphone-app/ui/000077500000000000000000000000001376717241300200275ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/ui/dev-modules/000077500000000000000000000000001376717241300222535ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/ui/dev-modules/Colors/000077500000000000000000000000001376717241300235145ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/ui/dev-modules/Colors/Colors.qml000066400000000000000000000022211376717241300254650ustar00rootroot00000000000000pragma Singleton import QtQml 2.2 // ============================================================================= QtObject { property color a: '#000000' property color b: '#000000' property color c: '#000000' property color d: '#000000' property color e: '#000000' property color f: '#000000' property color g: '#000000' property color g10: '#000000' property color g20: '#000000' property color g90: '#000000' property color h: '#000000' property color i: '#000000' property color i30: '#000000' property color j: '#000000' property color j75: '#000000' property color k: '#000000' property color l: '#000000' property color l50: '#000000' property color l80: '#000000' property color m: '#000000' property color n: '#000000' property color o: '#000000' property color p: '#000000' property color q: '#000000' property color r: '#000000' property color s: '#000000' property color t: '#000000' property color u: '#000000' property color v: '#000000' property color w: '#000000' property color x: '#000000' property color y: '#000000' property color z: '#000000' property color error: '#000000' } linphone-desktop-4.2.5/linphone-app/ui/dev-modules/Colors/qmldir000066400000000000000000000003601376717241300247260ustar00rootroot00000000000000# ============================================================================== # Colors component to export. # ============================================================================== module Colors singleton Colors 1.0 Colors.qml linphone-desktop-4.2.5/linphone-app/ui/dev-modules/Units/000077500000000000000000000000001376717241300233555ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/ui/dev-modules/Units/Units.qml000066400000000000000000000002321376717241300251670ustar00rootroot00000000000000pragma Singleton import QtQml 2.2 // ============================================================================= QtObject { property real dp: 1.0 } linphone-desktop-4.2.5/linphone-app/ui/dev-modules/Units/qmldir000066400000000000000000000003541376717241300245720ustar00rootroot00000000000000# ============================================================================== # Units component to export. # ============================================================================== module Units singleton Units 1.0 Units.qml linphone-desktop-4.2.5/linphone-app/ui/modules/000077500000000000000000000000001376717241300214775ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/ui/modules/Common/000077500000000000000000000000001376717241300227275ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/ui/modules/Common/Animations/000077500000000000000000000000001376717241300250315ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/ui/modules/Common/Animations/BusyIndicator.qml000066400000000000000000000040201376717241300303170ustar00rootroot00000000000000import QtQuick 2.7 import QtQuick.Controls 2.2 import Common.Styles 1.0 // ============================================================================= BusyIndicator { id: busyIndicator // --------------------------------------------------------------------------- property color color: BusyIndicatorStyle.color readonly property int _rotation: 360 readonly property int _size: width < height ? width : height // --------------------------------------------------------------------------- visible: running contentItem: Item { x: parent.width / 2 - width / 2 y: parent.height / 2 - height / 2 height: _size width: _size Item { id: item height: parent.height width: parent.width // ----------------------------------------------------------------------- // Animation. // ----------------------------------------------------------------------- RotationAnimator { duration: BusyIndicatorStyle.duration loops: Animation.Infinite running: busyIndicator.visible && busyIndicator.running target: item from: 0 to: busyIndicator._rotation } // ----------------------------------------------------------------------- // Items to draw. // ----------------------------------------------------------------------- Repeater { id: repeater model: BusyIndicatorStyle.nSpheres Rectangle { x: item.width / 2 - width / 2 y: item.height / 2 - height / 2 height: item.height / 3 width: item.width / 3 color: busyIndicator.color radius: (width > height ? width : height) / 2 transform: [ Translate { y: busyIndicator._size / 2 }, Rotation { angle: index / repeater.count * busyIndicator._rotation origin { x: width / 2 y: height / 2 } } ] } } } } } linphone-desktop-4.2.5/linphone-app/ui/modules/Common/Constants/000077500000000000000000000000001376717241300247035ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/ui/modules/Common/Constants/Constants.qml000066400000000000000000000003321376717241300273700ustar00rootroot00000000000000pragma Singleton import QtQuick 2.7 // ============================================================================= QtObject { property int zPopup: 999 property int zMax: 999999 property int sizeMax: 999999 } linphone-desktop-4.2.5/linphone-app/ui/modules/Common/Dialog/000077500000000000000000000000001376717241300241265ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/ui/modules/Common/Dialog/ConfirmDialog.qml000066400000000000000000000010351376717241300273550ustar00rootroot00000000000000import Common 1.0 import Common.Styles 1.0 // ============================================================================= // A dialog with OK/Cancel buttons. // ============================================================================= DialogPlus { buttons: [ TextButtonA { text: qsTr('cancel') onClicked: exit(0) }, TextButtonB { text: qsTr('confirm') onClicked: exit(1) } ] centeredButtons: true height: DialogStyle.confirmDialog.height width: DialogStyle.confirmDialog.width } linphone-desktop-4.2.5/linphone-app/ui/modules/Common/Dialog/DialogDescription.qml000066400000000000000000000015431376717241300302470ustar00rootroot00000000000000import QtQuick 2.7 import Common.Styles 1.0 // ============================================================================= // Description content used by dialogs. // ============================================================================= Item { property alias text: description.text height: !text ? DialogStyle.description.verticalMargin : undefined implicitHeight: text ? description.implicitHeight + DialogStyle.description.verticalMargin * 2 : 0 Text { id: description anchors { fill: parent leftMargin: DialogStyle.description.leftMargin rightMargin: DialogStyle.description.rightMargin } color: DialogStyle.description.color font.pointSize: DialogStyle.description.pointSize horizontalAlignment: Text.AlignHCenter verticalAlignment: Text.AlignVCenter wrapMode: Text.WordWrap } } linphone-desktop-4.2.5/linphone-app/ui/modules/Common/Dialog/DialogPlus.qml000066400000000000000000000042211376717241300267030ustar00rootroot00000000000000import QtQuick 2.7 import QtQuick.Layouts 1.3 import Common 1.0 import Common.Styles 1.0 // ============================================================================= // Helper to build quickly dialogs. // ============================================================================= Rectangle { id: dialog property alias buttons: buttons.data // Optionnal. property alias descriptionText: description.text // Optionnal. property bool centeredButtons: false default property alias _content: content.data property bool _disableExitStatus readonly property bool contentIsEmpty: { return _content == null || !_content.length } // --------------------------------------------------------------------------- signal exitStatus (int status) // --------------------------------------------------------------------------- function exit (status) { if (!_disableExitStatus) { _disableExitStatus = true exitStatus(status) } } // --------------------------------------------------------------------------- color: DialogStyle.color layer { enabled: true effect: PopupShadow {} } // --------------------------------------------------------------------------- Shortcut { sequence: StandardKey.Close onActivated: exit(0) } // --------------------------------------------------------------------------- ColumnLayout { anchors.fill: parent spacing: 0 DialogDescription { id: description Layout.fillHeight: dialog.contentIsEmpty Layout.fillWidth: true } Item { id: content Layout.fillHeight: !dialog.contentIsEmpty Layout.fillWidth: true Layout.leftMargin: DialogStyle.content.leftMargin Layout.rightMargin: DialogStyle.content.rightMargin } Row { id: buttons Layout.alignment: centeredButtons ? Qt.AlignHCenter : Qt.AlignLeft Layout.bottomMargin: DialogStyle.buttons.bottomMargin Layout.leftMargin: !centeredButtons ? DialogStyle.buttons.leftMargin : undefined Layout.topMargin: DialogStyle.buttons.topMargin spacing: DialogStyle.buttons.spacing } } } linphone-desktop-4.2.5/linphone-app/ui/modules/Common/Form/000077500000000000000000000000001376717241300236325ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/ui/modules/Common/Form/ActionBar.qml000066400000000000000000000004751376717241300262150ustar00rootroot00000000000000import QtQuick 2.7 import Common.Styles 1.0 // ============================================================================= // Bar which can contains ActionButtons. // ============================================================================= Row { property int iconSize spacing: ActionBarStyle.spacing } linphone-desktop-4.2.5/linphone-app/ui/modules/Common/Form/ActionButton.qml000066400000000000000000000036501376717241300267620ustar00rootroot00000000000000import QtQuick 2.7 import QtQuick.Controls 2.2 import Common 1.0 // ============================================================================= // An animated (or not) button with image(s). // ============================================================================= Item { id: wrappedButton // --------------------------------------------------------------------------- property bool enabled: true property bool updating: false property bool useStates: true property int iconSize // Optional. readonly property alias hovered: button.hovered property alias text: button.text // If `useStates` = true, the used icons are: // `icon`_pressed, `icon`_hovered and `icon`_normal. property string icon // --------------------------------------------------------------------------- signal clicked // --------------------------------------------------------------------------- function _getIcon () { if (wrappedButton.updating) { return wrappedButton.icon + '_updating' } if (!useStates) { return wrappedButton.icon } if (!wrappedButton.enabled) { return wrappedButton.icon + '_disabled' } return wrappedButton.icon + ( button.down ? '_pressed' : (button.hovered ? '_hovered' : '_normal') ) } // --------------------------------------------------------------------------- height: iconSize || parent.iconSize || parent.height width: iconSize || parent.iconSize || parent.width Button { id: button anchors.fill: parent background: Rectangle { color: 'transparent' } hoverEnabled: !wrappedButton.updating onClicked: !wrappedButton.updating && wrappedButton.enabled && wrappedButton.clicked() Icon { id: icon anchors.centerIn: parent icon: _getIcon() iconSize: wrappedButton.iconSize || ( parent.width > parent.height ? parent.height : parent.width ) } } } linphone-desktop-4.2.5/linphone-app/ui/modules/Common/Form/ActionSwitch.qml000066400000000000000000000014701376717241300267460ustar00rootroot00000000000000import QtQuick 2.7 // ============================================================================= Item { property alias updating: actionButton.updating property alias useStates: actionButton.useStates property alias text: actionButton.text property bool enabled: true property int iconSize // Optionnal. property string icon // --------------------------------------------------------------------------- signal clicked // --------------------------------------------------------------------------- height: iconSize || parent.iconSize || parent.height width: iconSize || parent.iconSize || parent.width ActionButton { id: actionButton anchors.fill: parent icon: parent.icon + (parent.enabled ? '_on' : '_off') iconSize: parent.iconSize onClicked: parent.clicked() } } linphone-desktop-4.2.5/linphone-app/ui/modules/Common/Form/Buttons/000077500000000000000000000000001376717241300252705ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/ui/modules/Common/Form/Buttons/AbstractTextButton.qml000066400000000000000000000041161376717241300316110ustar00rootroot00000000000000import QtQuick 2.7 import QtQuick.Controls 2.2 import Common 1.0 import Common.Styles 1.0 // ============================================================================= Item { id: wrappedButton property color colorDisabled property color colorHovered property color colorNormal property color colorPressed // By default textColorNormal is the hovered/pressed text color. property color textColorDisabled property color textColorHovered: textColorNormal property color textColorNormal property color textColorPressed: textColorNormal property alias text: button.text property bool enabled: true signal clicked // --------------------------------------------------------------------------- function _getBackgroundColor () { if (!wrappedButton.enabled) { return colorDisabled } return button.down ? colorPressed : (button.hovered ? colorHovered : colorNormal) } function _getTextColor () { if (!wrappedButton.enabled) { return textColorDisabled } return button.down ? textColorPressed : (button.hovered ? textColorHovered : textColorNormal) } // --------------------------------------------------------------------------- height: AbstractTextButtonStyle.background.height width: AbstractTextButtonStyle.background.width // --------------------------------------------------------------------------- Button { id: button background: Rectangle { color: _getBackgroundColor() radius: AbstractTextButtonStyle.background.radius } contentItem: Text { color: _getTextColor() font { bold: true pointSize: AbstractTextButtonStyle.text.pointSize } elide: Text.ElideRight horizontalAlignment: Text.AlignHCenter text: button.text verticalAlignment: Text.AlignVCenter } hoverEnabled: true MouseArea { id: mouseArea anchors.fill: parent onPressed: mouse.accepted = false } height: parent.height width: parent.width onClicked: wrappedButton.enabled && parent.clicked() } } linphone-desktop-4.2.5/linphone-app/ui/modules/Common/Form/Buttons/ExclusiveButtons.qml000066400000000000000000000030041376717241300313260ustar00rootroot00000000000000import QtQuick 2.7 import Common.Styles 1.0 // ============================================================================= Row { id: item // --------------------------------------------------------------------------- property int selectedButton: 0 property var texts // --------------------------------------------------------------------------- // Emitted when the selected button is changed. // Gives the selected button id. signal clicked (int button) // --------------------------------------------------------------------------- spacing: ExclusiveButtonsStyle.buttonsSpacing Keys.onLeftPressed: { if (selectedButton > 0) { clicked(--selectedButton) } } Keys.onRightPressed: { if (selectedButton < repeater.count - 1) { clicked(++selectedButton) } } // --------------------------------------------------------------------------- Repeater { id: repeater model: texts SmallButton { anchors.verticalCenter: parent.verticalCenter backgroundColor: selectedButton === index ? ExclusiveButtonsStyle.button.color.selected : (down ? ExclusiveButtonsStyle.button.color.pressed : (hovered ? ExclusiveButtonsStyle.button.color.hovered : ExclusiveButtonsStyle.button.color.normal ) ) text: modelData onClicked: { if (selectedButton !== index) { selectedButton = index item.clicked(index) } } } } } linphone-desktop-4.2.5/linphone-app/ui/modules/Common/Form/Buttons/ExclusiveButtons.spec.qml000066400000000000000000000037251376717241300322710ustar00rootroot00000000000000import QtQuick 2.7 import QtTest 1.1 // ============================================================================= Item { id: root function buildExclusiveButtons (defaultSelectedButton) { var container = builder.createObject(root) testCase.verify(container) container.data[0].selectedButton = defaultSelectedButton return container } // Avoid `Test 'XXX' has invalid size QSize(0, 0), resizing.` warning. height: 100 width: 300 Component { id: builder Item { ExclusiveButtons { id: exclusiveButtons texts: ['A', 'B', 'C', 'D', 'E'] } } } // --------------------------------------------------------------------------- TestCase { id: testCase when: windowShown function test_signals_data () { return [ { defaultSelectedButton: 0, buttonToClick: 2 }, { defaultSelectedButton: 1, buttonToClick: 4 }, { defaultSelectedButton: 3, buttonToClick: 1 }, { defaultSelectedButton: 4, buttonToClick: 0 } ] } function test_signals (data) { var container = buildExclusiveButtons(data.defaultSelectedButton) var exclusiveButtons = container.data[0] var buttonToClick = data.buttonToClick // Test default selected button. compare(exclusiveButtons.selectedButton, data.defaultSelectedButton) var button = -1 var count = 0 exclusiveButtons.clicked.connect(function (_button) { button = _button count += 1 }) // Test a click to change the selected button. mouseClick(exclusiveButtons.data[buttonToClick]) compare(button, buttonToClick) compare(exclusiveButtons.selectedButton, buttonToClick) compare(count, 1) // No signal must be emitted. mouseClick(exclusiveButtons.data[buttonToClick]) compare(button, buttonToClick) compare(exclusiveButtons.selectedButton, buttonToClick) compare(count, 1) container.destroy() } } } linphone-desktop-4.2.5/linphone-app/ui/modules/Common/Form/Buttons/FileChooserButton.qml000066400000000000000000000046331376717241300314070ustar00rootroot00000000000000import QtQuick 2.7 import QtQuick.Dialogs 1.2 import Common 1.0 import Common.Styles 1.0 import Utils 1.0 // ============================================================================= TextField { id: textField // --------------------------------------------------------------------------- property alias selectExisting: fileDialog.selectExisting property alias selectFolder: fileDialog.selectFolder property alias title: fileDialog.title property string selectedFile: '' // --------------------------------------------------------------------------- signal accepted (var selectedFile) signal rejected // --------------------------------------------------------------------------- text: { var path = textField.selectedFile return path.length ? path : '' } tools: Item { height: parent.height width: FileChooserButtonStyle.tools.width Rectangle { anchors { fill: parent margins: TextFieldStyle.background.border.width } color: mouseArea.pressed ? FileChooserButtonStyle.tools.button.color.pressed : ( mouseArea.containsMouse ? FileChooserButtonStyle.tools.button.color.hovered : FileChooserButtonStyle.tools.button.color.normal ) Icon { anchors.centerIn: parent icon: (textField.selectFolder ? 'folder' : 'file') + (mouseArea.pressed ? '_pressed' : ( mouseArea.containsMouse ? '_hovered' : '_normal' ) ) iconSize: FileChooserButtonStyle.tools.button.iconSize } } } // --------------------------------------------------------------------------- FileDialog { id: fileDialog folder: { var selectedFile = textField.selectedFile if (!selectedFile.length) { return '' } return Utils.getUriFromSystemPath( textField.selectFolder ? selectedFile : Utils.dirname(selectedFile) ) } onAccepted: { var selectedFile = Utils.getSystemPathFromUri(fileUrl) textField.selectedFile = selectedFile textField.accepted(selectedFile) } onRejected: textField.rejected() } // --------------------------------------------------------------------------- MouseArea { id: mouseArea anchors.fill: parent enabled: !textField.readOnly onClicked: fileDialog.open() } } linphone-desktop-4.2.5/linphone-app/ui/modules/Common/Form/Buttons/SmallButton.qml000066400000000000000000000020351376717241300302470ustar00rootroot00000000000000import QtQuick 2.7 import QtQuick.Controls 2.2 import Common 1.0 import Common.Styles 1.0 // ============================================================================= Button { id: button property alias backgroundColor: background.color background: Rectangle { id: background color: button.down ? SmallButtonStyle.background.color.pressed : (button.hovered ? SmallButtonStyle.background.color.hovered : SmallButtonStyle.background.color.normal ) implicitHeight: SmallButtonStyle.background.height radius: SmallButtonStyle.background.radius } contentItem: Text { color: SmallButtonStyle.text.color font.pointSize: SmallButtonStyle.text.pointSize horizontalAlignment: Text.AlignHCenter text: button.text verticalAlignment: Text.AlignVCenter leftPadding: SmallButtonStyle.leftPadding rightPadding: SmallButtonStyle.rightPadding } hoverEnabled: true MouseArea { id: mouseArea anchors.fill: parent onPressed: mouse.accepted = false } } linphone-desktop-4.2.5/linphone-app/ui/modules/Common/Form/Buttons/TextButtonA.qml000066400000000000000000000011041376717241300302200ustar00rootroot00000000000000import Common.Styles 1.0 // ============================================================================= AbstractTextButton { colorDisabled: TextButtonAStyle.backgroundColor.disabled colorHovered: TextButtonAStyle.backgroundColor.hovered colorNormal: TextButtonAStyle.backgroundColor.normal colorPressed: TextButtonAStyle.backgroundColor.pressed textColorDisabled: TextButtonAStyle.textColor.disabled textColorHovered: TextButtonAStyle.textColor.hovered textColorNormal: TextButtonAStyle.textColor.normal textColorPressed: TextButtonAStyle.textColor.pressed } linphone-desktop-4.2.5/linphone-app/ui/modules/Common/Form/Buttons/TextButtonB.qml000066400000000000000000000011041376717241300302210ustar00rootroot00000000000000import Common.Styles 1.0 // ============================================================================= AbstractTextButton { colorDisabled: TextButtonBStyle.backgroundColor.disabled colorHovered: TextButtonBStyle.backgroundColor.hovered colorNormal: TextButtonBStyle.backgroundColor.normal colorPressed: TextButtonBStyle.backgroundColor.pressed textColorDisabled: TextButtonBStyle.textColor.disabled textColorHovered: TextButtonBStyle.textColor.hovered textColorNormal: TextButtonBStyle.textColor.normal textColorPressed: TextButtonBStyle.textColor.pressed } linphone-desktop-4.2.5/linphone-app/ui/modules/Common/Form/CheckBoxText.qml000066400000000000000000000032241376717241300267010ustar00rootroot00000000000000import QtQuick 2.7 import QtQuick.Controls 2.2 import Common.Styles 1.0 // ============================================================================= // Checkbox with clickable text. // ============================================================================= CheckBox { id: checkBox contentItem: Text { color: checkBox.down ? CheckBoxTextStyle.color.pressed : ( checkBox.hovered ? CheckBoxTextStyle.color.hovered : CheckBoxTextStyle.color.normal ) elide: Text.ElideRight font: checkBox.font leftPadding: checkBox.indicator.width + checkBox.spacing text: checkBox.text width: parent.width wrapMode: Text.WordWrap verticalAlignment: Text.AlignVCenter } font.pointSize: CheckBoxTextStyle.pointSize hoverEnabled: true indicator: Rectangle { border.color: checkBox.down ? CheckBoxTextStyle.color.pressed : ( checkBox.hovered ? CheckBoxTextStyle.color.hovered : CheckBoxTextStyle.color.normal ) implicitHeight: CheckBoxTextStyle.size implicitWidth: CheckBoxTextStyle.size radius: CheckBoxTextStyle.radius x: checkBox.leftPadding y: parent.height / 2 - height / 2 Rectangle { color: checkBox.down ? CheckBoxTextStyle.color.pressed : (checkBox.hovered ? CheckBoxTextStyle.color.hovered : CheckBoxTextStyle.color.normal ) height: parent.height - y * 2 width: parent.width - x * 2 radius: CheckBoxTextStyle.radius visible: checkBox.checked x: 4 // Fixed, no needed to use style file. y: 4 // Same thing. } } } linphone-desktop-4.2.5/linphone-app/ui/modules/Common/Form/ComboBox.js000066400000000000000000000044701376717241300257050ustar00rootroot00000000000000/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ // ============================================================================= // `ComboBox.qml` Logic. // ============================================================================= .import 'qrc:/ui/scripts/Utils/utils.js' as Utils // ============================================================================= function getSelectedEntryIcon () { var iconRole = comboBox.iconRole if (iconRole == null || iconRole.length === 0) { return '' } var currentIndex = comboBox.currentIndex if (currentIndex < 0) { return '' } var model = comboBox.model if (Utils.isFunction(iconRole)) { return iconRole( Utils.isArray(model) ? model[currentIndex] : model.get(currentIndex) ) } return ( Utils.isArray(model) ? model[currentIndex][iconRole] : model.get(currentIndex)[iconRole] ) || '' } function getSelectedEntryText () { if (comboBox.currentIndex < 0) { return '' } var text = comboBox.displayText if (text.length > 0) { return text } // With a `QAbstractListModel`, `text` is empty. QML bug? var model = comboBox.model if (model.data) { var item = model.data(model.index(comboBox.currentIndex, 0)) var textRole = comboBox.textRole return textRole.length > 0 ? item[textRole] : item } return '' } function getItemIcon (item) { var iconRole = comboBox.iconRole if (iconRole == null || iconRole.length === 0) { return '' } return Utils.isFunction(iconRole) ? iconRole(item.flattenedModel) : item.flattenedModel[iconRole] } linphone-desktop-4.2.5/linphone-app/ui/modules/Common/Form/ComboBox.qml000066400000000000000000000044301376717241300260560ustar00rootroot00000000000000import QtQuick 2.7 import QtQuick.Controls 2.2 as Controls import QtQuick.Layouts 1.3 import Common 1.0 import Common.Styles 1.0 import 'ComboBox.js' as Logic // ============================================================================= Controls.ComboBox { id: comboBox // --------------------------------------------------------------------------- property var iconRole // --------------------------------------------------------------------------- background: Rectangle { border { color: ComboBoxStyle.background.border.color width: ComboBoxStyle.background.border.width } color: comboBox.enabled ? ComboBoxStyle.background.color.normal : ComboBoxStyle.background.color.readOnly radius: ComboBoxStyle.background.radius implicitHeight: ComboBoxStyle.background.height implicitWidth: ComboBoxStyle.background.width } // --------------------------------------------------------------------------- contentItem: Item { height: comboBox.height width: comboBox.width RowLayout { anchors { fill: parent leftMargin: ComboBoxStyle.contentItem.leftMargin } spacing: ComboBoxStyle.contentItem.spacing Icon { icon: Logic.getSelectedEntryIcon() iconSize: ComboBoxStyle.contentItem.iconSize visible: icon.length > 0 } Text { Layout.fillWidth: true color: ComboBoxStyle.contentItem.text.color elide: Text.ElideRight font.pointSize: ComboBoxStyle.contentItem.text.pointSize rightPadding: comboBox.indicator.width + comboBox.spacing text: Logic.getSelectedEntryText() } } } // --------------------------------------------------------------------------- indicator: Icon { icon: 'drop_down' iconSize: ComboBoxStyle.background.iconSize x: comboBox.width - width - comboBox.rightPadding y: comboBox.topPadding + (comboBox.availableHeight - height) / 2 } // --------------------------------------------------------------------------- delegate: CommonItemDelegate { id: item container: comboBox flattenedModel: comboBox.textRole.length && (typeof modelData !== 'undefined' ? modelData : model) itemIcon: Logic.getItemIcon(item) width: comboBox.width } } linphone-desktop-4.2.5/linphone-app/ui/modules/Common/Form/CommonItemDelegate.qml000066400000000000000000000033661376717241300300570ustar00rootroot00000000000000import QtQuick 2.7 import QtQuick.Controls 2.2 as Controls import QtQuick.Layouts 1.3 import Common 1.0 import Common.Styles 1.0 // ============================================================================= Controls.ItemDelegate { id: item property var container property var flattenedModel property var itemIcon default property alias _content: content.data hoverEnabled: true background: Rectangle { color: item.hovered ? CommonItemDelegateStyle.color.hovered : CommonItemDelegateStyle.color.normal Rectangle { anchors.left: parent.left color: CommonItemDelegateStyle.indicator.color height: parent.height width: CommonItemDelegateStyle.indicator.width visible: item.hovered } Rectangle { anchors.bottom: parent.bottom color: CommonItemDelegateStyle.separator.color height: CommonItemDelegateStyle.separator.height width: parent.width visible: container.count !== index + 1 } } contentItem: RowLayout { spacing: CommonItemDelegateStyle.contentItem.spacing width: item.width Icon { icon: item.itemIcon iconSize: CommonItemDelegateStyle.contentItem.iconSize visible: icon.length > 0 } Text { Layout.fillWidth: true color: CommonItemDelegateStyle.contentItem.text.color elide: Text.ElideRight font { bold: container.currentIndex === index pointSize: CommonItemDelegateStyle.contentItem.text.pointSize } text: item.flattenedModel[container.textRole] || modelData } Item { id: content Layout.preferredWidth: CommonItemDelegateStyle.contentItem.iconSize Layout.preferredHeight: CommonItemDelegateStyle.contentItem.iconSize } } } linphone-desktop-4.2.5/linphone-app/ui/modules/Common/Form/DroppableTextArea.qml000066400000000000000000000074051376717241300277210ustar00rootroot00000000000000import QtQuick 2.7 import QtQuick.Controls 2.2 import QtQuick.Dialogs 1.2 import Common 1.0 import Common.Styles 1.0 import Utils 1.0 // ============================================================================= Item { id: droppableTextArea property alias placeholderText: textArea.placeholderText property alias text: textArea.text property alias cursorPosition: textArea.cursorPosition property bool dropEnabled: true property string dropDisabledReason // --------------------------------------------------------------------------- signal dropped (var files) signal validText (string text) // --------------------------------------------------------------------------- function _emitFiles (files) { // Filtering files, other urls are forbidden. files = files.reduce(function (files, file) { if (file.startsWith('file:')) { files.push(Utils.getSystemPathFromUri(file)) } return files }, []) if (files.length > 0) { dropped(files) } } // --------------------------------------------------------------------------- // Text area. Flickable { anchors.fill: parent boundsBehavior: Flickable.StopAtBounds ScrollBar.vertical: ForceScrollBar { id: scrollBar } TextArea.flickable: TextArea { id: textArea function handleValidation () { if (text.length !== 0) { validText(text) } } background: Rectangle { color: DroppableTextAreaStyle.backgroundColor } color: DroppableTextAreaStyle.text.color font.pointSize: DroppableTextAreaStyle.text.pointSize rightPadding: fileChooserButton.width + fileChooserButton.anchors.rightMargin + DroppableTextAreaStyle.fileChooserButton.margins selectByMouse: true wrapMode: TextArea.Wrap // Workaround. Without this line, the scrollbar is not linked correctly // to the text area. width: parent.width Component.onCompleted: forceActiveFocus() Keys.onPressed: { if (event.matches(StandardKey.InsertLineSeparator)) { insert(cursorPosition, '') } else if (event.key === Qt.Key_Return || event.key === Qt.Key_Enter) { handleValidation() event.accepted = true } } } } // Handle click to select files. ActionButton { id: fileChooserButton anchors { right: parent.right rightMargin: scrollBar.width + DroppableTextAreaStyle.fileChooserButton.margins verticalCenter: parent.verticalCenter } enabled: droppableTextArea.dropEnabled icon: 'attachment' iconSize: DroppableTextAreaStyle.fileChooserButton.size onClicked: fileDialog.open() FileDialog { id: fileDialog folder: shortcuts.home title: qsTr('fileChooserTitle') onAccepted: _emitFiles(fileDialog.fileUrls) } TooltipArea { text: droppableTextArea.dropEnabled ? qsTr('attachmentTooltip') : droppableTextArea.dropDisabledReason } } // Hovered style. Rectangle { id: hoverContent anchors.fill: parent color: DroppableTextAreaStyle.hoverContent.backgroundColor visible: false Text { anchors.centerIn: parent color: DroppableTextAreaStyle.hoverContent.text.color font.pointSize: DroppableTextAreaStyle.hoverContent.text.pointSize text: qsTr('dropYourAttachment') } } DropArea { anchors.fill: parent keys: [ 'text/uri-list' ] visible: droppableTextArea.dropEnabled onDropped: { state = '' if (drop.hasUrls) { _emitFiles(drop.urls) } } onEntered: state = 'hover' onExited: state = '' states: State { name: 'hover' PropertyChanges { target: hoverContent; visible: true } } } } linphone-desktop-4.2.5/linphone-app/ui/modules/Common/Form/Fields/000077500000000000000000000000001376717241300250405ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/ui/modules/Common/Form/Fields/HexField.qml000066400000000000000000000022341376717241300272440ustar00rootroot00000000000000import QtQuick 2.7 import Common.Styles 1.0 // ============================================================================= Item { id: wrapper // --------------------------------------------------------------------------- property alias readOnly: textField.readOnly property string text // --------------------------------------------------------------------------- signal editingFinished (int value) // --------------------------------------------------------------------------- function _computeText (text) { return (+text).toString(16).toUpperCase() } // --------------------------------------------------------------------------- implicitHeight: textField.height width: TextFieldStyle.background.width // --------------------------------------------------------------------------- Binding { property: 'text' target: textField value: _computeText(wrapper.text) } TextField { id: textField validator: RegExpValidator { regExp: /[0-9A-Fa-f]*/ } width: parent.width onEditingFinished: { text = _computeText('0x' + text) wrapper.editingFinished(parseInt(text, 16)) } } } linphone-desktop-4.2.5/linphone-app/ui/modules/Common/Form/Fields/NumericField.qml000066400000000000000000000047551376717241300301340ustar00rootroot00000000000000import QtQuick 2.7 import QtQuick.Controls 2.2 import Common 1.0 import Common.Styles 1.0 // ============================================================================= TextField { id: numericField property int maxValue: 9999 property int minValue: 0 property int step: 1 // --------------------------------------------------------------------------- function _decrease () { var value = +numericField.text if (value === minValue) { return } numericField.text = value - step >= minValue ? value - step : minValue numericField.editingFinished() } function _increase () { var value = +numericField.text if (value === maxValue) { return } numericField.text = value + step <= maxValue ? value + step : maxValue numericField.editingFinished() } // --------------------------------------------------------------------------- text: minValue tools: Item { height: parent.height width: NumericFieldStyle.tools.width Column { id: container anchors { fill: parent margins: TextFieldStyle.background.border.width } // ----------------------------------------------------------------------- Component { id: button Button { id: buttonInstance autoRepeat: true background: Rectangle { color: buttonInstance.down && !numericField.readOnly ? NumericFieldStyle.tools.button.color.pressed : NumericFieldStyle.tools.button.color.normal } contentItem: Text { color: NumericFieldStyle.tools.button.text.color text: buttonInstance.text font.pointSize: NumericFieldStyle.tools.button.text.pointSize horizontalAlignment: Text.AlignHCenter verticalAlignment: Text.AlignVCenter } text: parent.text height: container.height / 2 width: container.width onClicked: !numericField.readOnly && handler() } } // ----------------------------------------------------------------------- Loader { property string text: '+' property var handler: _increase sourceComponent: button } Loader { property string text: '-' property var handler: _decrease sourceComponent: button } } } validator: IntValidator { bottom: numericField.minValue top: numericField.maxValue } } linphone-desktop-4.2.5/linphone-app/ui/modules/Common/Form/Fields/PasswordField.qml000066400000000000000000000002461376717241300303230ustar00rootroot00000000000000import QtQuick 2.7 import Common 1.0 // ============================================================================= TextField { echoMode: TextInput.Password } linphone-desktop-4.2.5/linphone-app/ui/modules/Common/Form/Fields/PortField.qml000066400000000000000000000035731376717241300274530ustar00rootroot00000000000000import QtQuick 2.7 import Common.Styles 1.0 import Utils 1.0 // ============================================================================= Item { id: wrapper // --------------------------------------------------------------------------- property alias readOnly: textField.readOnly property bool supportsRange: false property string text // --------------------------------------------------------------------------- signal editingFinished (int portA, int portB) // --------------------------------------------------------------------------- function _extractPorts (text) { var portA = +text.split(':')[0] var portB = (function () { var port = text.split(':')[1] return port && port.length > 0 ? +port : -1 })() if (portB < 0 || portA === portB) { return [ portA, -1 ] } if (portA < portB) { return [ portA, portB ] } return [ portB, portA ] } function _computeText (range) { return range[1] < 0 ? range[0] : range[0] + ':' + range[1] } // --------------------------------------------------------------------------- implicitHeight: textField.height width: TextFieldStyle.background.width // --------------------------------------------------------------------------- Binding { property: 'text' target: textField value: _computeText(_extractPorts(wrapper.text)) } TextField { id: textField validator: RegExpValidator { regExp: wrapper.supportsRange ? Utils.PORT_RANGE_REGEX : Utils.PORT_REGEX } width: parent.width // Workaround to supports empty string. Keys.onReturnPressed: editingFinished() onActiveFocusChanged: !activeFocus && editingFinished() onEditingFinished: { var range = _extractPorts(text) textField.text = _computeText(range) wrapper.editingFinished(range[0], range[1]) } } } linphone-desktop-4.2.5/linphone-app/ui/modules/Common/Form/Fields/ScrollableListViewField.qml000066400000000000000000000016151376717241300322730ustar00rootroot00000000000000import QtQuick 2.7 import Common 1.0 import Common.Styles 1.0 // ============================================================================= Rectangle { id: field property bool readOnly: false default property alias _content: content.data color: TextFieldStyle.background.color.normal radius: TextFieldStyle.background.radius Item { id: content anchors.fill: parent } Rectangle { anchors.fill: parent border { color: TextFieldStyle.background.border.color.normal width: TextFieldStyle.background.border.width } color: 'transparent' radius: field.radius } Rectangle { anchors.fill: parent color: TextFieldStyle.background.color.readOnly opacity: 0.8 visible: field.readOnly } MouseArea { anchors.fill: parent cursorShape: Qt.ArrowCursor visible: field.readOnly onWheel: wheel.accepted = true } } linphone-desktop-4.2.5/linphone-app/ui/modules/Common/Form/Fields/TextAreaField.qml000066400000000000000000000024051376717241300302350ustar00rootroot00000000000000import QtQuick 2.7 import QtQuick.Controls 2.2 import Common 1.0 import Common.Styles 1.0 // ============================================================================= Flickable { property alias text: textArea.text readonly property alias length: textArea.length boundsBehavior: Flickable.StopAtBounds height: TextAreaFieldStyle.background.height width: TextAreaFieldStyle.background.width ScrollBar.vertical: ForceScrollBar { id: scrollBar } TextArea.flickable: TextArea { id: textArea background: Rectangle { border { color: TextAreaFieldStyle.background.border.color width: TextAreaFieldStyle.background.border.width } color: textArea.readOnly ? TextAreaFieldStyle.background.color.readOnly : TextAreaFieldStyle.background.color.normal radius: TextAreaFieldStyle.background.radius } color: TextAreaFieldStyle.text.color font.pointSize: TextAreaFieldStyle.text.pointSize selectByMouse: true wrapMode: TextArea.Wrap bottomPadding: TextAreaFieldStyle.text.padding leftPadding: TextAreaFieldStyle.text.padding rightPadding: TextAreaFieldStyle.text.padding + Number(scrollBar.visible) * scrollBar.width topPadding: TextAreaFieldStyle.text.padding } } linphone-desktop-4.2.5/linphone-app/ui/modules/Common/Form/Fields/TextField.qml000066400000000000000000000047201376717241300274460ustar00rootroot00000000000000import QtQuick 2.7 import QtQuick.Controls 2.2 as Controls import Common 1.0 import Common.Styles 1.0 // ============================================================================= // A classic TextInput which supports an icon attribute. // ============================================================================= Controls.TextField { id: textField // --------------------------------------------------------------------------- property alias icon: icon.icon property string error: '' property var tools // --------------------------------------------------------------------------- background: Rectangle { border { color: textField.error.length > 0 ? TextFieldStyle.background.border.color.error : ( textField.activeFocus && !textField.readOnly ? TextFieldStyle.background.border.color.selected : TextFieldStyle.background.border.color.normal ) width: TextFieldStyle.background.border.width } color: textField.readOnly ? TextFieldStyle.background.color.readOnly : TextFieldStyle.background.color.normal implicitHeight: TextFieldStyle.background.height implicitWidth: TextFieldStyle.background.width radius: TextFieldStyle.background.radius MouseArea { anchors.right: parent.right height: parent.height cursorShape: Qt.ArrowCursor implicitWidth: tools ? tools.width : 0 Rectangle { id: toolsContainer border { color: textField.error.length > 0 ? TextFieldStyle.background.border.color.error : TextFieldStyle.background.border.color.normal width: TextFieldStyle.background.border.width } anchors.fill: parent color: background.color data: tools || [] } } } color: TextFieldStyle.text.color font.pointSize: TextFieldStyle.text.pointSize rightPadding: TextFieldStyle.text.rightPadding + toolsContainer.width selectByMouse: true // --------------------------------------------------------------------------- onEditingFinished: cursorPosition = 0 onTextChanged: { if (!focus) { cursorPosition = 0 } } // --------------------------------------------------------------------------- Icon { id: icon anchors { right: parent.right rightMargin: parent.rightPadding verticalCenter: parent.verticalCenter } iconSize: parent.contentHeight visible: !parent.text } } linphone-desktop-4.2.5/linphone-app/ui/modules/Common/Form/ListForm.js000066400000000000000000000056601376717241300257360ustar00rootroot00000000000000/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ // ============================================================================= // `ListForm.qml` Logic. // ============================================================================= .import 'qrc:/ui/scripts/Utils/utils.js' as Utils // ============================================================================= function setData (data) { var model = values.model model.clear() data.forEach(function (data) { model.append({ $value: data, $isInvalid: false }) }) } function setInvalid (index, status) { Utils.assert( index >= 0 && index < values.model.count, 'Index ' + index + 'not exists.' ) values.model.setProperty(index, '$isInvalid', status) } function updateValue (index, value) { var model = values.model // Unable to set property directly. Qt uses a cache of the value. // It's necessary to remove then insert. model.remove(index) model.insert(index, { $isInvalid: false, $value: value }) } // ----------------------------------------------------------------------------- function addValue (value) { values.model.append({ $value: value, $isInvalid: false }) if (value.length === 0) { addButton.enabled = false } } function handleEditionFinished (index, text) { var model = values.model var oldValue = model.get(index).$value if (text.length === 0) { // No changes. It must exists at least n min values. if (minValues != null && minValues >= model.count) { updateValue(index, oldValue) return } model.remove(index) if (oldValue.length !== 0) { listForm.removed(index, oldValue) } } else if (text !== oldValue) { // Update changes. updateValue(index, text) listForm.changed(index, oldValue, text) } addButton.enabled = true } function handleItemCreation () { if (this.text.length === 0) { // FIXME: Find the source of this problem. // // Magic code. If it's the first inserted value, // an event or a callback steal the item focus. // I suppose it's an internal Qt qml event... // // So, I choose to run a callback executed after this // internal event. Utils.setTimeout(values, 0, this.forceActiveFocus) } } linphone-desktop-4.2.5/linphone-app/ui/modules/Common/Form/ListForm.qml000066400000000000000000000066441376717241300261160ustar00rootroot00000000000000import QtQuick 2.7 import QtQuick.Layouts 1.3 import Common 1.0 import Common.Styles 1.0 import 'ListForm.js' as Logic // ============================================================================= RowLayout { id: listForm // --------------------------------------------------------------------------- property alias placeholder: placeholder.text property alias title: text.text property bool readOnly: false property int inputMethodHints property var minValues readonly property int count: values.count // --------------------------------------------------------------------------- signal changed (int index, string oldValue, string newValue) signal removed (int index, string value) // --------------------------------------------------------------------------- function setData () { Logic.setData.apply(this, arguments) } function setInvalid () { Logic.setInvalid.apply(this, arguments) } function updateValue () { Logic.updateValue.apply(this, arguments) } // --------------------------------------------------------------------------- spacing: 0 // --------------------------------------------------------------------------- // Title area. // --------------------------------------------------------------------------- RowLayout { Layout.alignment: Qt.AlignTop Layout.preferredHeight: ListFormStyle.lineHeight spacing: ListFormStyle.titleArea.spacing ActionButton { id: addButton icon: 'add' iconSize: ListFormStyle.titleArea.iconSize opacity: !listForm.readOnly ? 1 : 0 onClicked: !listForm.readOnly && Logic.addValue('') } Text { id: text Layout.preferredWidth: ListFormStyle.titleArea.text.width color: ListFormStyle.titleArea.text.color elide: Text.ElideRight font { bold: true pointSize: ListFormStyle.titleArea.text.pointSize } } } // --------------------------------------------------------------------------- // Placeholder. // --------------------------------------------------------------------------- Text { id: placeholder Layout.fillWidth: true Layout.preferredHeight: ListFormStyle.lineHeight color: ListFormStyle.value.placeholder.color font { italic: true pointSize: ListFormStyle.value.placeholder.pointSize } padding: ListFormStyle.value.text.padding visible: values.model.count === 0 verticalAlignment: Text.AlignVCenter MouseArea { anchors.fill: parent onClicked: !listForm.readOnly && Logic.addValue('') } } // --------------------------------------------------------------------------- // Values. // --------------------------------------------------------------------------- ListView { id: values Layout.fillWidth: true Layout.preferredHeight: count * ListFormStyle.lineHeight interactive: false visible: model.count > 0 delegate: Item { implicitHeight: textInput.height width: parent.width TransparentTextInput { id: textInput inputMethodHints: listForm.inputMethodHints isInvalid: $isInvalid readOnly: listForm.readOnly text: $value height: ListFormStyle.lineHeight width: parent.width Component.onCompleted: Logic.handleItemCreation.apply(this) onEditingFinished: Logic.handleEditionFinished(index, text) } } model: ListModel {} } } linphone-desktop-4.2.5/linphone-app/ui/modules/Common/Form/ListItemSelector.js000066400000000000000000000025231376717241300274250ustar00rootroot00000000000000/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ // ============================================================================= // `ListItemSelector.qml` Logic. // ============================================================================= .import 'qrc:/ui/scripts/Utils/utils.js' as Utils // ============================================================================= function getItemIcon (item) { var iconRole = view.iconRole if (iconRole == null || iconRole.length === 0) { return '' } return Utils.isFunction(iconRole) ? iconRole(item.flattenedModel) : item.flattenedModel[iconRole] } linphone-desktop-4.2.5/linphone-app/ui/modules/Common/Form/ListItemSelector.qml000066400000000000000000000017211376717241300276010ustar00rootroot00000000000000import Common 1.0 import 'ListItemSelector.js' as Logic // ============================================================================= ScrollableListViewField { property alias currentIndex: view.currentIndex property alias iconRole: view.iconRole property alias model: view.model property alias textRole: view.textRole signal activated (int index) radius: 0 ScrollableListView { id: view // ------------------------------------------------------------------------- property string textRole property var iconRole // ------------------------------------------------------------------------- anchors.fill: parent currentIndex: -1 delegate: CommonItemDelegate { id: item container: view flattenedModel: view.textRole.length && (typeof modelData !== 'undefined' ? modelData : model) itemIcon: Logic.getItemIcon(item) width: parent.width onClicked: activated(index) } } } linphone-desktop-4.2.5/linphone-app/ui/modules/Common/Form/MouseArea.qml000066400000000000000000000003341376717241300262260ustar00rootroot00000000000000import QtQuick 2.7 as Quick import Common 1.0 import Common.Styles 1.0 Quick.MouseArea { cursorShape: containsMouse ? Qt.PointingHandCursor : Qt.ArrowCursor hoverEnabled: true } linphone-desktop-4.2.5/linphone-app/ui/modules/Common/Form/Placements/000077500000000000000000000000001376717241300257255ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/ui/modules/Common/Form/Placements/Form.qml000066400000000000000000000017361376717241300273520ustar00rootroot00000000000000import QtQuick 2.7 import QtQuick.Layouts 1.3 import Common.Styles 1.0 // ============================================================================= Column { property alias title: title.text property bool dealWithErrors: false property int orientation: Qt.Horizontal // --------------------------------------------------------------------------- spacing: FormStyle.spacing // --------------------------------------------------------------------------- ColumnLayout { spacing: FormStyle.header.spacing visible: parent.title.length > 0 width: parent.width Text { id: title color: FormStyle.header.title.color font { bold: true pointSize: FormStyle.header.title.pointSize } } Rectangle { Layout.fillWidth: true Layout.preferredHeight: FormStyle.header.separator.height color: FormStyle.header.separator.color } Item { height: FormStyle.header.bottomMargin } } } linphone-desktop-4.2.5/linphone-app/ui/modules/Common/Form/Placements/FormEmptyLine.qml000066400000000000000000000003071376717241300311720ustar00rootroot00000000000000import QtQuick 2.7 import Common.Styles 1.0 // ============================================================================= Item { height: FormHGroupStyle.legend.height width: parent.width } linphone-desktop-4.2.5/linphone-app/ui/modules/Common/Form/Placements/FormGroup.qml000066400000000000000000000015641376717241300303660ustar00rootroot00000000000000import QtQuick 2.7 // ============================================================================= Loader { id: loader // --------------------------------------------------------------------------- property string label readonly property int orientation: parent.orientation readonly property bool dealWithErrors: parent.dealWithErrors default property var _content: null // --------------------------------------------------------------------------- sourceComponent: orientation === Qt.Horizontal ? hGroup : vGroup width: parent.maxItemWidth // --------------------------------------------------------------------------- Component { id: hGroup FormHGroup { _content: loader._content label: loader.label } } Component { id: vGroup FormVGroup { _content: loader._content label: loader.label } } } linphone-desktop-4.2.5/linphone-app/ui/modules/Common/Form/Placements/FormHGroup.qml000066400000000000000000000033111376717241300304660ustar00rootroot00000000000000import QtQuick 2.7 import QtQuick.Layouts 1.3 import Common 1.0 import Common.Styles 1.0 // ============================================================================= RowLayout { property alias label: label.text default property var _content: null // --------------------------------------------------------------------------- spacing: FormHGroupStyle.spacing // --------------------------------------------------------------------------- Text { id: label Layout.preferredHeight: FormHGroupStyle.legend.height Layout.preferredWidth: FormHGroupStyle.legend.width color: FormHGroupStyle.legend.color elide: Text.ElideRight font.pointSize: FormHGroupStyle.legend.pointSize horizontalAlignment: Text.AlignRight verticalAlignment: Text.AlignVCenter TooltipArea { delay: 0 text: parent.text visible: parent.truncated } } // --------------------------------------------------------------------------- Item { readonly property int currentHeight: _content ? _content.height : 0 Layout.alignment: ( currentHeight < FormHGroupStyle.legend.height ? Qt.AlignVCenter : Qt.AlignTop ) | Qt.AlignLeft Layout.fillWidth: true Layout.preferredHeight: currentHeight Loader { active: !!_content anchors.fill: parent sourceComponent: Item { id: content data: [ _content ] width: parent.width Component.onCompleted: _content.width = Qt.binding(function () { var contentWidth = content.width var wishedWidth = FormHGroupStyle.content.maxWidth return contentWidth > wishedWidth ? wishedWidth : contentWidth }) } } } } linphone-desktop-4.2.5/linphone-app/ui/modules/Common/Form/Placements/FormLine.qml000066400000000000000000000013671376717241300301620ustar00rootroot00000000000000import QtQuick 2.7 import Common.Styles 1.0 // ============================================================================= Row { readonly property double maxItemWidth: { var n = children.length var curWidth = width / n - (n - 1) * spacing var maxWidth = orientation === Qt.Horizontal ? FormHGroupStyle.legend.width + FormHGroupStyle.content.maxWidth + FormHGroupStyle.spacing : FormVGroupStyle.content.maxWidth return curWidth < maxWidth ? curWidth : maxWidth } readonly property int orientation: parent.orientation readonly property bool dealWithErrors: parent.dealWithErrors // --------------------------------------------------------------------------- spacing: FormLineStyle.spacing width: parent.width } linphone-desktop-4.2.5/linphone-app/ui/modules/Common/Form/Placements/FormTable.qml000066400000000000000000000026701376717241300303200ustar00rootroot00000000000000import QtQuick 2.7 import Common.Styles 1.0 // ============================================================================= Column { id: formTable property alias titles: header.model property bool disableLineTitle: false property int legendLineWidth: FormTableStyle.entry.width readonly property double maxItemWidth: { var n = titles.length var curWidth = (width - FormTableStyle.entry.width) / n - (n - 1) * FormTableLineStyle.spacing var maxWidth = FormTableStyle.entry.maxWidth return curWidth < maxWidth ? curWidth : maxWidth } // --------------------------------------------------------------------------- spacing: FormTableStyle.spacing width: parent.width // --------------------------------------------------------------------------- Row { spacing: FormTableLineStyle.spacing width: parent.width // No title for the titles column. Item { height: FormTableStyle.entry.height width: formTable.legendLineWidth visible: !formTable.disableLineTitle } Repeater { id: header Text { id: text color: FormTableStyle.entry.text.color elide: Text.ElideRight horizontalAlignment: Text.AlignHCenter text: modelData height: FormTableStyle.entry.height width: formTable.maxItemWidth font { bold: true pointSize: FormTableStyle.entry.text.pointSize } } } } } linphone-desktop-4.2.5/linphone-app/ui/modules/Common/Form/Placements/FormTableEntry.qml000066400000000000000000000011021376717241300313270ustar00rootroot00000000000000import QtQuick 2.7 import Common.Styles 1.0 // ============================================================================= Item { default property var _content readonly property int currentHeight: _content ? _content.height : 0 // --------------------------------------------------------------------------- height: currentHeight width: parent.maxItemWidth Loader { active: !!_content anchors.fill: parent sourceComponent: Item { id: item data: [ _content ] Component.onCompleted: _content.anchors.centerIn = item } } } linphone-desktop-4.2.5/linphone-app/ui/modules/Common/Form/Placements/FormTableLine.qml000066400000000000000000000016211376717241300311230ustar00rootroot00000000000000import QtQuick 2.7 import QtQuick.Layouts 1.3 import Common.Styles 1.0 // ============================================================================= Row { id: formTableLine property alias title: title.text readonly property double maxItemWidth: parent.maxItemWidth // --------------------------------------------------------------------------- spacing: FormLineStyle.spacing width: parent.width // --------------------------------------------------------------------------- Text { id: title color: FormTableStyle.entry.text.color elide: Text.ElideRight horizontalAlignment: Text.AlignRight verticalAlignment: Text.AlignVCenter height: FormTableStyle.entry.height width: formTableLine.parent.legendLineWidth font { bold: false pointSize: FormTableStyle.entry.text.pointSize } visible: !formTableLine.parent.disableLineTitle } } linphone-desktop-4.2.5/linphone-app/ui/modules/Common/Form/Placements/FormVGroup.qml000066400000000000000000000035201376717241300305060ustar00rootroot00000000000000import QtQuick 2.7 import QtQuick.Layouts 1.3 import Common 1.0 import Common.Styles 1.0 // ============================================================================= ColumnLayout { property alias label: label.text default property var _content: null // --------------------------------------------------------------------------- spacing: FormVGroupStyle.spacing width: parent.maxItemWidth // --------------------------------------------------------------------------- Text { id: label Layout.fillWidth: true color: FormVGroupStyle.legend.color elide: Text.ElideRight font.pointSize: FormVGroupStyle.legend.pointSize verticalAlignment: Text.AlignVCenter TooltipArea { delay: 0 text: parent.text visible: parent.truncated } } // --------------------------------------------------------------------------- Item { readonly property int currentHeight: _content ? _content.height : 0 Layout.fillWidth: true Layout.preferredHeight: currentHeight Loader { active: !!_content anchors.fill: parent sourceComponent: Item { id: content data: [ _content ] width: parent.width Component.onCompleted: _content.width = Qt.binding(function () { var contentWidth = content.width var wishedWidth = FormVGroupStyle.content.maxWidth return contentWidth > wishedWidth ? wishedWidth : contentWidth }) } } } Text { Layout.fillWidth: true Layout.preferredHeight: FormVGroupStyle.error.height color: FormVGroupStyle.error.color elide: Text.ElideRight font { italic: true pointSize: FormVGroupStyle.error.pointSize } text: _content && _content.error && _content.error.length ? _content.error : '' visible: parent.parent.dealWithErrors } } linphone-desktop-4.2.5/linphone-app/ui/modules/Common/Form/SearchBox.qml000066400000000000000000000076311376717241300262320ustar00rootroot00000000000000import QtQuick 2.7 import QtQuick.Controls 2.2 as Controls import Common 1.0 import Utils 1.0 // ============================================================================= Item { id: searchBox // --------------------------------------------------------------------------- readonly property alias filter: searchField.text readonly property alias isOpen: searchBox._isOpen readonly property var view: _content[0] property alias entryHeight: menu.entryHeight property alias maxMenuHeight: menu.maxMenuHeight property alias placeholderText: searchField.placeholderText property alias tooltipText : tooltip.text default property alias _content: menu._content property bool _isOpen: false // --------------------------------------------------------------------------- signal menuClosed signal menuOpened signal menuRequested signal enterPressed // --------------------------------------------------------------------------- function closeMenu () { if (!_isOpen) { return } searchBox.state = '' _isOpen = false } function openMenu () { if (_isOpen) { return } searchBox.state = 'opened' _isOpen = true } function _filter (text) { var model = searchBox.view.model Utils.assert(model.setFilter != null, '`model.setFilter` must be defined.') model.setFilter(text) } // --------------------------------------------------------------------------- implicitHeight: searchField.height Item { implicitHeight: searchField.height + menu.height width: parent.width TextField { id: searchField icon: 'search' readOnly: !searchBox.enabled width: parent.width Keys.onEscapePressed: searchBox.closeMenu() Keys.onReturnPressed: { searchBox.enterPressed() searchBox.closeMenu() } onActiveFocusChanged: { if (activeFocus && !_isOpen) { searchBox.menuRequested() searchBox.openMenu() } } onTextChanged: _filter(text) } // ------------------------------------------------------------------------- DropDownDynamicMenu { id: menu relativeTo: searchField relativeY: searchField.height // If the menu is focused, the main window loses the active status. // So It's necessary to map the keys events. Keys.forwardTo: searchField onClosed: searchBox.closeMenu() } Binding { target: searchBox.view property: 'width' value: searchField.width } Binding { target: searchBox.view property: 'headerPositioning' value: searchBox.view.header ? ListView.OverlayHeader : ListView.InlineFooter } } MouseArea {// Just take hover events and set popup to do its automatic close if mouse is not inside field/popup area anchors.fill: parent onContainsMouseChanged: menu.popup.closePolicy=(containsMouse?Controls.Popup.NoAutoClose:Controls.Popup.CloseOnEscape | Controls.Popup.CloseOnPressOutside) hoverEnabled:true preventStealing: true propagateComposedEvents:true onPressed: mouse.accepted=false onReleased: mouse.accepted=false onClicked: mouse.accepted=false onDoubleClicked: mouse.accepted=false onPressAndHold: mouse.accepted=false TooltipArea { id:tooltip visible: !isOpen && text !== '' } } // --------------------------------------------------------------------------- states: State { name: 'opened' } transitions: [ Transition { from: '' to: 'opened' ScriptAction { script: { menu.open() searchBox.menuOpened() } } }, Transition { from: 'opened' to: '' ScriptAction { script: { menu.close() searchField.focus = false searchField.text = '' searchBox.menuClosed() } } } ] } linphone-desktop-4.2.5/linphone-app/ui/modules/Common/Form/Slider.qml000066400000000000000000000024471376717241300255760ustar00rootroot00000000000000import QtQuick 2.7 import QtQuick.Controls 2.2 as Controls import Common.Styles 1.0 // ============================================================================= Controls.Slider { id: slider background: Rectangle { color: SliderStyle.background.color x: slider.leftPadding y: slider.topPadding + slider.availableHeight / 2 - height / 2 implicitHeight: SliderStyle.background.height implicitWidth: SliderStyle.background.width height: implicitHeight width: slider.availableWidth radius: SliderStyle.background.radius Rectangle { color: SliderStyle.background.content.color height: parent.height width: slider.visualPosition * parent.width radius: SliderStyle.background.content.radius } } handle: Rectangle { border.color: slider.pressed ? SliderStyle.handle.border.color.pressed : SliderStyle.handle.border.color.normal color: slider.pressed ? SliderStyle.handle.color.pressed : SliderStyle.handle.color.normal x: slider.leftPadding + slider.visualPosition * (slider.availableWidth - width) y: slider.topPadding + slider.availableHeight / 2 - height / 2 implicitWidth: SliderStyle.handle.width implicitHeight: SliderStyle.handle.height radius: SliderStyle.handle.radius } } linphone-desktop-4.2.5/linphone-app/ui/modules/Common/Form/StaticListForm.qml000066400000000000000000000027521376717241300272620ustar00rootroot00000000000000import QtQuick 2.7 import QtQuick.Layouts 1.3 import Common.Styles 1.0 // ============================================================================= RowLayout { id: form property alias title: text.text property bool readOnly: false property var fields signal changed (int index, string value) // --------------------------------------------------------------------------- function _handleEditionFinished (index, text) { if (text !== fields[index].text) { form.changed(index, text) } } // --------------------------------------------------------------------------- spacing: 0 Text { id: text Layout.alignment: Qt.AlignTop Layout.leftMargin: ListFormStyle.titleArea.iconSize + ListFormStyle.titleArea.spacing Layout.preferredHeight: ListFormStyle.lineHeight Layout.preferredWidth: ListFormStyle.titleArea.text.width color: ListFormStyle.titleArea.text.color elide: Text.ElideRight font { bold: true pointSize: ListFormStyle.titleArea.text.pointSize } verticalAlignment: Text.AlignVCenter } ColumnLayout { Layout.fillWidth: true spacing: 0 Repeater { model: form.fields TransparentTextInput { Layout.fillWidth: true Layout.preferredHeight: ListFormStyle.lineHeight placeholder: modelData.placeholder || '' readOnly: form.readOnly text: modelData.text || '' onEditingFinished: _handleEditionFinished(index, text) } } } } linphone-desktop-4.2.5/linphone-app/ui/modules/Common/Form/Switch.qml000066400000000000000000000047761376717241300256240ustar00rootroot00000000000000import QtQuick 2.7 import QtQuick.Controls 2.2 import Common 1.0 import Common.Styles 1.0 // ============================================================================= Switch { id: control // --------------------------------------------------------------------------- property bool enabled: true // --------------------------------------------------------------------------- signal clicked // --------------------------------------------------------------------------- checked: false indicator: Rectangle { implicitHeight: SwitchStyle.indicator.height implicitWidth: SwitchStyle.indicator.width border.color: control.enabled ? ( control.checked ? SwitchStyle.indicator.border.color.checked : SwitchStyle.indicator.border.color.normal ) : SwitchStyle.indicator.border.color.disabled color: control.enabled ? ( control.checked ? SwitchStyle.indicator.color.checked : SwitchStyle.indicator.color.normal ) : SwitchStyle.indicator.color.disabled radius: SwitchStyle.indicator.radius x: control.leftPadding y: parent.height / 2 - height / 2 Rectangle { id: sphere height: SwitchStyle.sphere.size width: SwitchStyle.sphere.size anchors.verticalCenter: parent.verticalCenter border.color: control.enabled ? ( control.checked ? ( control.down ? SwitchStyle.sphere.border.color.pressed : SwitchStyle.sphere.border.color.checked ) : SwitchStyle.sphere.border.color.normal ) : SwitchStyle.sphere.border.color.disabled color: control.enabled ? ( control.down ? SwitchStyle.sphere.color.pressed : SwitchStyle.sphere.color.normal ) : SwitchStyle.sphere.color.disabled radius: width / 2 // ----------------------------------------------------------------------- states: State { when: control.checked PropertyChanges { target: sphere x: parent.width - width } } transitions: Transition { NumberAnimation { properties: 'x' duration: SwitchStyle.animation.duration easing.type: Easing.InOutQuad } } } } // --------------------------------------------------------------------------- MouseArea { anchors.fill: parent onClicked: control.enabled && control.clicked() } } linphone-desktop-4.2.5/linphone-app/ui/modules/Common/Form/Tab/000077500000000000000000000000001376717241300243405ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/ui/modules/Common/Form/Tab/TabBar.qml000066400000000000000000000002141376717241300262030ustar00rootroot00000000000000import QtQuick 2.7 import QtQuick.Controls 2.2 // ============================================================================= TabBar {} linphone-desktop-4.2.5/linphone-app/ui/modules/Common/Form/Tab/TabButton.qml000066400000000000000000000047361376717241300267670ustar00rootroot00000000000000import QtQuick 2.7 import QtQuick.Controls 2.2 as Controls import QtQuick.Layouts 1.3 import Common 1.0 import Common.Styles 1.0 // ============================================================================= Controls.TabButton { id: button // --------------------------------------------------------------------------- property int iconSize: TabButtonStyle.icon.size property string iconName readonly property bool _isSelected: parent.parent.currentItem === button // --------------------------------------------------------------------------- function _getBackgroundColor () { if (_isSelected) { return TabButtonStyle.backgroundColor.selected } return button.enabled ? ( button.down ? TabButtonStyle.backgroundColor.pressed : ( button.hovered ? TabButtonStyle.backgroundColor.hovered : TabButtonStyle.backgroundColor.normal ) ) : TabButtonStyle.backgroundColor.disabled } function _getTextColor () { if (_isSelected) { return TabButtonStyle.text.color.selected } return button.enabled ? ( button.down ? TabButtonStyle.text.color.pressed : ( button.hovered ? TabButtonStyle.text.color.hovered : TabButtonStyle.text.color.normal ) ) : TabButtonStyle.text.color.disabled } // --------------------------------------------------------------------------- background: Rectangle { color: _getBackgroundColor() implicitHeight: TabButtonStyle.text.height } contentItem: RowLayout { height: button.height width: button.width spacing: TabButtonStyle.spacing Icon { id: icon Layout.fillHeight: true Layout.leftMargin: TabButtonStyle.text.leftPadding icon: { var iconName = button.iconName return iconName.length ? (iconName + '_' + (button._isSelected ? 'selected' : 'normal')) : '' } iconSize: button.iconSize } Text { Layout.fillWidth: true Layout.fillHeight: true color: _getTextColor() font { bold: true pointSize: TabButtonStyle.text.pointSize } elide: Text.ElideRight height: parent.height horizontalAlignment: Text.AlignHCenter verticalAlignment: Text.AlignVCenter rightPadding: TabButtonStyle.text.rightPadding text: button.text } } hoverEnabled: true } linphone-desktop-4.2.5/linphone-app/ui/modules/Common/Form/Tab/TabContainer.qml000066400000000000000000000024331376717241300274260ustar00rootroot00000000000000import QtQuick 2.7 import QtQuick.Controls 2.2 import QtQuick.Layouts 1.3 import Common 1.0 import Common.Styles 1.0 import Utils 1.0 // ============================================================================= Rectangle { default property alias _content: content.data color: TabContainerStyle.color ColumnLayout { anchors.fill: parent spacing: 0 Flickable { ScrollBar.vertical: ForceScrollBar { id: scrollBar } Layout.fillHeight: true Layout.fillWidth: true boundsBehavior: Flickable.StopAtBounds clip: true contentHeight: Utils.ensureArray(_content).reduce(function (acc, item) { return item.height }, 0, []) + TabContainerStyle.topMargin + TabContainerStyle.bottomMargin contentWidth: width Item { id: content anchors { left: parent.left leftMargin: TabContainerStyle.leftMargin right: parent.right rightMargin: TabContainerStyle.rightMargin top: parent.top topMargin: TabContainerStyle.topMargin } } } Rectangle { Layout.fillWidth: true Layout.preferredHeight: TabContainerStyle.separator.height color: TabContainerStyle.separator.color visible: scrollBar.visible } } } linphone-desktop-4.2.5/linphone-app/ui/modules/Common/Form/TransparentTextInput.qml000066400000000000000000000054071376717241300305410ustar00rootroot00000000000000import QtQuick 2.7 import Common 1.0 import Common.Styles 1.0 // ============================================================================= // A editable text that has a background color on focus. // ============================================================================= Item { property alias color: textInput.color property alias font: textInput.font property alias inputMethodHints: textInput.inputMethodHints property alias placeholder: placeholder.text property alias readOnly: textInput.readOnly property alias text: textInput.text property bool forceFocus: false property bool isInvalid: false property int padding: TransparentTextInputStyle.padding // --------------------------------------------------------------------------- signal editingFinished // --------------------------------------------------------------------------- onActiveFocusChanged: { if (activeFocus) { textInput.focus = true } } Rectangle { id: background color: (textInput.activeFocus || parent.forceFocus) && !textInput.readOnly ? TransparentTextInputStyle.backgroundColor : // No Style constant, see component name. // It's a `transparent` TextInput. 'transparent' height: parent.height width: { var width = textInput.contentWidth + parent.padding * 2 return width < parent.width ? width : parent.width } InvertedMouseArea { anchors.fill: parent enabled: textInput.activeFocus onPressed: textInput.focus = false } } Icon { id: icon anchors.left: background.right height: background.height icon: 'generic_error' iconSize: TransparentTextInputStyle.iconSize visible: parent.isInvalid } Text { id: placeholder anchors.centerIn: parent color: TransparentTextInputStyle.placeholder.color elide: Text.ElideRight font { italic: true pointSize: TransparentTextInputStyle.placeholder.pointSize } height: textInput.height width: textInput.width verticalAlignment: Text.AlignVCenter visible: textInput.text.length === 0 && (!textInput.activeFocus || textInput.readOnly) } TextInput { id: textInput anchors.centerIn: parent height: parent.height width: parent.width - parent.padding * 2 clip: true color: activeFocus && !readOnly ? TransparentTextInputStyle.text.color.focused : TransparentTextInputStyle.text.color.normal font.pointSize: TransparentTextInputStyle.text.pointSize selectByMouse: true verticalAlignment: TextInput.AlignVCenter Keys.onEscapePressed: focus = false Keys.onReturnPressed: focus = false onEditingFinished: { cursorPosition = 0 if (!parent.readOnly) { parent.editingFinished() } } } } linphone-desktop-4.2.5/linphone-app/ui/modules/Common/Helpers/000077500000000000000000000000001376717241300243315ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/ui/modules/Common/Helpers/DragBox.qml000066400000000000000000000047261376717241300264030ustar00rootroot00000000000000import QtQuick 2.7 import Common 1.0 // ============================================================================= Item { id: dragBox // --------------------------------------------------------------------------- property var container property var draggable property var xPosition property var yPosition // --------------------------------------------------------------------------- property var _mouseArea: null // --------------------------------------------------------------------------- signal pressed (var mouse) signal released (var mouse) signal wheel (var wheel) // --------------------------------------------------------------------------- function _create () { draggable.x = Qt.binding(xPosition) draggable.y = Qt.binding(yPosition) var drag = draggable.Drag drag.hotSpot.x = Qt.binding(function () { return draggable.width / 2 }) drag.hotSpot.y = Qt.binding(function () { return draggable.height / 2 }) if (_mouseArea == null) { _mouseArea = builder.createObject(draggable) drag.active = Qt.binding(function () { return _mouseArea && _mouseArea.held }) drag.source = Qt.binding(function () { return _mouseArea }) } } function _delete () { if (_mouseArea != null) { _mouseArea.destroy() _mouseArea = null } } // --------------------------------------------------------------------------- Component.onCompleted: enabled && _create() Component.onDestruction: _delete() onEnabledChanged: { _delete() if (enabled) { _create() } } // --------------------------------------------------------------------------- Component { id: builder MouseArea { property bool held: false anchors.fill: parent drag { axis: Drag.XandYAxis target: parent } onPressed: { dragBox.pressed(mouse) held = true } onReleased: { dragBox.released(mouse) held = false var container = dragBox.container if (parent.x < 0) { parent.x = 0 } else if (parent.x + parent.width >= container.width) { parent.x = container.width - parent.width } if (parent.y < 0) { parent.y = 0 } else if (parent.y + parent.height >= container.height) { parent.y = container.height - parent.height } } onWheel: dragBox.wheel(wheel) } } } linphone-desktop-4.2.5/linphone-app/ui/modules/Common/Helpers/InvertedMouseArea.qml000066400000000000000000000062241376717241300304320ustar00rootroot00000000000000import QtQuick 2.7 import Common 1.0 import Utils 1.0 // ============================================================================= // Helper to handle button click outside an item. // ============================================================================= Item { id: item // --------------------------------------------------------------------------- property bool _mouseAlwaysOutside property var _mouseArea: null // --------------------------------------------------------------------------- // When emitted, returns a function to test if the click // is on a specific item. It takes only a item parameter. signal pressed (var pointIsInItem) // --------------------------------------------------------------------------- function _createMouseArea () { var parent = Utils.getTopParent(item, true) if (_mouseArea == null) { _mouseArea = builder.createObject() } _mouseArea.parent = parent // Must be true if a fake parent is used and if `mouseArea` // is not in the same window that `item`. _mouseAlwaysOutside = _mouseArea.parent !== Utils.getTopParent(item) } function _deleteMouseArea () { if (_mouseArea != null) { _mouseArea.destroy() _mouseArea = null } } // --------------------------------------------------------------------------- // It's necessary to use a `enabled` variable. // See: http://doc.qt.io/qt-5/qml-qtqml-component.html#completed-signal // // The creation order of components in a view is undefined, // so the mouse area must be created only when the target component // was completed. Component.onCompleted: enabled && _createMouseArea() Component.onDestruction: _deleteMouseArea() onEnabledChanged: { _deleteMouseArea() if (enabled) { _createMouseArea() } } Component { id: builder MouseArea { cursorShape: Qt.ArrowCursor property var _timeout function _checkPosition (positionEvent) { // Propagate event. positionEvent.accepted = false // Click is outside or not. if ( _mouseAlwaysOutside || !Utils.pointIsInItem(this, item, positionEvent) ) { if (_timeout != null) { // Remove existing timeout to avoid the creation of // many children. Utils.clearTimeout(_timeout) } // Use a asynchronous call that is executed // after the propagated event. // // It's useful to ensure the window's context is not // modified with the positionEvent before the `onPressed` // call. // // The timeout is destroyed with the `MouseArea` component. _timeout = Utils.setTimeout(this, 0, item.pressed.bind( this, (function (point, item) { return Utils.pointIsInItem(this, item, point) }).bind(this, { x: positionEvent.x, y: positionEvent.y }) )) } } anchors.fill: parent propagateComposedEvents: true z: Constants.zMax onPressed: _checkPosition.call(this, mouse) onWheel: _checkPosition.call(this, wheel) } } } linphone-desktop-4.2.5/linphone-app/ui/modules/Common/Helpers/InvertedMouseArea.spec.qml000066400000000000000000000054311376717241300313620ustar00rootroot00000000000000import QtQuick 2.7 import QtTest 1.1 import Utils 1.0 import Common 1.0 // ============================================================================= Rectangle { id: root color: 'violet' height: 200 width: 300 Rectangle { id: item color: 'pink' height: 80 width: 100 x: 120 y: 100 InvertedMouseArea { id: invertedMouseArea anchors.fill: parent } } SignalSpy { id: spy signalName: 'pressed' target: invertedMouseArea } TestCase { when: windowShown function init () { spy.clear() } function test_randomClickInsideMouseArea () { Utils.times(100, function () { var x = Math.floor(Utils.genRandomNumber(item.x, item.x + width)) var y = Math.floor(Utils.genRandomNumber(item.y, item.y + height)) mouseClick(root, x, y) }) wait(100) compare(spy.count, 0, '`pressed` signal was emitted') } // ------------------------------------------------------------------------- function test_randomClickOutsideMouseArea () { Utils.times(50, function () { var x = Math.floor(Utils.genRandomNumberBetweenIntervals([ [ 0, item.x ], [ item.x + item.width, root.width ] ])) var y = Math.floor(Utils.genRandomNumberBetweenIntervals([ [ 0, item.y ], [ item.y + item.height, root.height ] ])) mouseClick(root, x, y) spy.wait(100) }) Utils.times(50, function () { var x = Math.floor(Utils.genRandomNumber(item.x, item.x + item.width)) var y = Math.floor(Utils.genRandomNumberBetweenIntervals([ [ 0, item.y ], [ item.y + item.height, root.height ] ])) mouseClick(root, x, y) spy.wait(100) }) } // ------------------------------------------------------------------------- function test_clickInsideMouseArea_data () { return [ { x: item.x, y: item.y }, { x: item.x + item.width - 1, y: item.y }, { x: item.x, y: item.y + item.height - 1}, { x: item.x + item.width - 1, y: item.y + item.height - 1 }, { } // (x, y) = item center. ] } function test_clickInsideMouseArea (data) { mouseClick(root, data.x, data.y) wait(100) compare(spy.count, 0, '`pressed` signal was emitted') } // ------------------------------------------------------------------------- function test_clickOutsideMouseArea_data () { return [ { x: item.x - 1, y: item.y - 1}, { x: item.x + item.width, y: item.y }, { x: item.x, y: item.y + item.height }, { x: item.x + item.width, y: item.y + item.height } ] } function test_clickOutsideMouseArea (data) { mouseClick(root, data.x, data.y) spy.wait(100) } } } linphone-desktop-4.2.5/linphone-app/ui/modules/Common/Image/000077500000000000000000000000001376717241300237515ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/ui/modules/Common/Image/Icon.qml000066400000000000000000000015651376717241300253630ustar00rootroot00000000000000import QtQuick 2.7 import Common 1.0 import Utils 1.0 // ============================================================================= // An icon image properly resized. // ============================================================================= Item { property var iconSize // Required. property string icon height: iconSize width: iconSize Image { mipmap: Qt.platform.os === 'osx' function getIconSize () { Utils.assert( iconSize != null && iconSize >= 0, '`iconSize` must be defined and must be positive. (icon=`' + icon + '`, iconSize=' + iconSize + ')' ) return iconSize } anchors.centerIn: parent width: iconSize height: iconSize fillMode: Image.PreserveAspectFit source: Utils.resolveImageUri(icon) sourceSize.width: getIconSize() sourceSize.height: getIconSize() } } linphone-desktop-4.2.5/linphone-app/ui/modules/Common/Image/RoundedImage.qml000066400000000000000000000032721376717241300270330ustar00rootroot00000000000000import QtQuick 2.7 // ============================================================================= Item { id: item property alias source: image.source property color backgroundColor: '#00000000' property color foregroundColor: '#00000000' readonly property alias status: image.status Item { id: imageContainer anchors.fill: parent layer.enabled: true visible: false Image { id: image mipmap: Qt.platform.os === 'osx' anchors.fill: parent fillMode: Image.PreserveAspectCrop sourceSize.width: parent.width sourceSize.height: parent.height } } Rectangle { anchors.fill: parent layer { effect: ShaderEffect { property color backgroundColor: item.backgroundColor property color foregroundColor: item.foregroundColor property var image: imageContainer // See: https://www.opengl.org/sdk/docs/man/html/mix.xhtml fragmentShader: ' #ifdef GL_ES precision lowp float; #endif uniform sampler2D image; uniform sampler2D mask; uniform vec4 backgroundColor; uniform vec4 foregroundColor; uniform float qt_Opacity; varying vec2 qt_TexCoord0; void main () { vec4 tex = texture2D(image, qt_TexCoord0); vec4 interpolation = mix(backgroundColor, vec4(tex.rgb, 1.0), tex.a); interpolation = mix(interpolation, vec4(foregroundColor.rgb, 1.0), foregroundColor.a); gl_FragColor = interpolation * texture2D(mask, qt_TexCoord0) * qt_Opacity; } ' } enabled: true samplerName: 'mask' } radius: width / 2 } } linphone-desktop-4.2.5/linphone-app/ui/modules/Common/Indicators/000077500000000000000000000000001376717241300250265ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/ui/modules/Common/Indicators/VuMeter.qml000066400000000000000000000027671376717241300271440ustar00rootroot00000000000000import QtQuick 2.7 import QtQuick.Controls 2.2 import Common.Styles 1.0 // ============================================================================= Column { id: vuMeter property bool enabled: true property double value: 0 height: VuMeterStyle.height width: VuMeterStyle.width // --------------------------------------------------------------------------- ProgressBar { id: high height: parent.height * 0.25 width: parent.width from: 0.75 to: 1.0 value: parent.value background: Rectangle { color: vuMeter.enabled ? VuMeterStyle.high.background.color.enabled : VuMeterStyle.high.background.color.disabled } contentItem: Item { Rectangle { anchors.bottom: parent.bottom color: VuMeterStyle.high.contentItem.color height: high.visualPosition * parent.height width: parent.width visible: vuMeter.enabled } } } ProgressBar { id: low height: parent.height * 0.75 width: parent.width from: 0 to: 0.75 value: parent.value background: Rectangle { color: vuMeter.enabled ? VuMeterStyle.low.background.color.enabled : VuMeterStyle.low.background.color.disabled } contentItem: Item { Rectangle { anchors.bottom: parent.bottom color: VuMeterStyle.low.contentItem.color height: low.visualPosition * parent.height width: parent.width visible: vuMeter.enabled } } } } linphone-desktop-4.2.5/linphone-app/ui/modules/Common/Menus/000077500000000000000000000000001376717241300240165ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/ui/modules/Common/Menus/ApplicationMenu.qml000066400000000000000000000017611376717241300276260ustar00rootroot00000000000000import QtQuick 2.7 import QtQuick.Layouts 1.3 import Common.Styles 1.0 // ============================================================================= // Responsive flat menu with visual indicators. // ============================================================================= Rectangle { id: menu // --------------------------------------------------------------------------- property var defaultSelectedEntry: null property int entryHeight property int entryWidth property var _selected: defaultSelectedEntry default property alias _content: content.data // --------------------------------------------------------------------------- function resetSelectedEntry () { _selected = null } // --------------------------------------------------------------------------- color: ApplicationMenuStyle.backgroundColor implicitHeight: content.height width: entryWidth Column { id: content width: parent.width spacing: ApplicationMenuStyle.spacing } } linphone-desktop-4.2.5/linphone-app/ui/modules/Common/Menus/ApplicationMenuEntry.qml000066400000000000000000000044731376717241300306530ustar00rootroot00000000000000import QtQuick 2.7 import QtQuick.Layouts 1.3 import Common 1.0 import Common.Styles 1.0 // ============================================================================= Rectangle { id: entry // --------------------------------------------------------------------------- property string icon property alias name: text.text readonly property bool isSelected: parent.parent._selected === this // --------------------------------------------------------------------------- signal selected // --------------------------------------------------------------------------- function select () { var menu = parent.parent if (menu._selected !== this) { menu._selected = this selected() } } // --------------------------------------------------------------------------- color: mouseArea.pressed ? ApplicationMenuStyle.entry.color.pressed : (isSelected ? ApplicationMenuStyle.entry.color.selected : (mouseArea.containsMouse ? ApplicationMenuStyle.entry.color.hovered : ApplicationMenuStyle.entry.color.normal ) ) height: parent.parent.entryHeight width: parent.parent.entryWidth RowLayout { anchors { left: parent.left leftMargin: ApplicationMenuStyle.entry.leftMargin right: parent.right rightMargin: ApplicationMenuStyle.entry.rightMargin verticalCenter: parent.verticalCenter } spacing: ApplicationMenuStyle.entry.spacing Icon { icon: entry.icon + ( entry.isSelected ? '_selected' : '_normal' ) iconSize: ApplicationMenuStyle.entry.iconSize } Text { id: text Layout.fillWidth: true color: entry.isSelected ? ApplicationMenuStyle.entry.text.color.selected : ApplicationMenuStyle.entry.text.color.normal font.pointSize: ApplicationMenuStyle.entry.text.pointSize height: parent.height text: entry.name verticalAlignment: Text.AlignVCenter } } Rectangle { anchors { left: parent.left } height: parent.height color: entry.isSelected ? ApplicationMenuStyle.entry.indicator.color : 'transparent' width: ApplicationMenuStyle.entry.indicator.width } MouseArea { id: mouseArea anchors.fill: parent onClicked: entry.select() } } linphone-desktop-4.2.5/linphone-app/ui/modules/Common/Menus/DropDownDynamicMenu.qml000066400000000000000000000037251376717241300304260ustar00rootroot00000000000000import QtQuick 2.7 import Common 1.0 import Utils 1.0 // ============================================================================= Item { id: menu // --------------------------------------------------------------------------- property alias relativeTo: popup.relativeTo property alias relativeX: popup.relativeX property alias relativeY: popup.relativeY // Can be computed, but for performance usage, it must be given in attribute. property int entryHeight property int maxMenuHeight default property alias _content: menuContent.data property alias popup : popup // --------------------------------------------------------------------------- signal closed signal opened // --------------------------------------------------------------------------- function open () { popup.open() } function close () { popup.close() } // --------------------------------------------------------------------------- function _computeHeight () { Utils.assert(_content != null && _content.length > 0, '`_content` cannot be null and must exists.') var list = _content[0] Utils.assert(list != null, 'No list found.') var height = list.count * entryHeight if (list.headerPositioning === ListView.OverlayHeader) { // Workaround to force header layout. list.headerItem.z = Constants.zMax height += list.headerItem.height } return (maxMenuHeight !== undefined && height > maxMenuHeight) ? maxMenuHeight : height } // --------------------------------------------------------------------------- visible: false // --------------------------------------------------------------------------- Popup { id: popup onOpened: menu.opened() onClosed: menu.closed() Item { id: menuContent height: menu._computeHeight() width: menu._content[0].width } } Binding { property: 'height' target: menu._content[0] value: menuContent.height } } linphone-desktop-4.2.5/linphone-app/ui/modules/Common/Menus/DropDownStaticMenu.qml000066400000000000000000000024101376717241300302570ustar00rootroot00000000000000import QtQuick 2.7 import QtQuick.Layouts 1.3 import Common 1.0 import Common.Styles 1.0 // ============================================================================= Item { id: menu // --------------------------------------------------------------------------- property alias relativeTo: popup.relativeTo property alias relativeX: popup.relativeX property alias relativeY: popup.relativeY property alias entryHeight: content.entryHeight property alias entryWidth: content.entryWidth default property alias _content: content.data // --------------------------------------------------------------------------- signal closed signal opened // --------------------------------------------------------------------------- function open () { popup.open() } function close () { popup.close() } // --------------------------------------------------------------------------- visible: false // --------------------------------------------------------------------------- Popup { id: popup onOpened: menu.opened() onClosed: menu.closed() Column { id: content property int entryHeight property int entryWidth spacing: DropDownStaticMenuStyle.spacing width: menu.entryWidth } } } linphone-desktop-4.2.5/linphone-app/ui/modules/Common/Menus/DropDownStaticMenuEntry.qml000066400000000000000000000020111376717241300312760ustar00rootroot00000000000000import QtQuick 2.7 import Common 1.0 import Common.Styles 1.0 // ============================================================================= Rectangle { id: entry property alias entryName: text.text signal clicked color: mouseArea.pressed ? DropDownStaticMenuStyle.entry.color.pressed : (mouseArea.containsMouse ? DropDownStaticMenuStyle.entry.color.hovered : DropDownStaticMenuStyle.entry.color.normal ) height: parent.entryHeight width: parent.entryWidth Text { id: text anchors { left: parent.left leftMargin: DropDownStaticMenuStyle.entry.leftMargin right: parent.right rightMargin: DropDownStaticMenuStyle.entry.rightMargin } color: DropDownStaticMenuStyle.entry.text.color elide: Text.ElideRight font.pointSize: DropDownStaticMenuStyle.entry.text.pointSize height: parent.height verticalAlignment: Text.AlignVCenter } MouseArea { id: mouseArea anchors.fill: parent onClicked: entry.clicked() } } linphone-desktop-4.2.5/linphone-app/ui/modules/Common/Menus/Menu.qml000066400000000000000000000005701376717241300254370ustar00rootroot00000000000000import QtQuick 2.7 import QtQuick.Controls 2.2 as Controls import Common 1.0 import Common.Styles 1.0 // ============================================================================= Controls.Menu { id: menu background: Rectangle { implicitWidth: MenuStyle.width color: MenuStyle.color layer { enabled: true effect: PopupShadow {} } } } linphone-desktop-4.2.5/linphone-app/ui/modules/Common/Menus/MenuItem.qml000066400000000000000000000016021376717241300262530ustar00rootroot00000000000000import QtQuick 2.7 import QtQuick.Controls 2.2 import Common.Styles 1.0 // ============================================================================= MenuItem { id: button background: Rectangle { color: button.down ? MenuItemStyle.background.color.pressed : ( button.hovered ? MenuItemStyle.background.color.hovered : MenuItemStyle.background.color.normal ) implicitHeight: MenuItemStyle.background.height } contentItem: Text { color: button.enabled ? MenuItemStyle.text.color.enabled : MenuItemStyle.text.color.disabled elide: Text.ElideRight font { bold: true pointSize: MenuItemStyle.text.pointSize } text: button.text leftPadding: MenuItemStyle.leftPadding rightPadding: MenuItemStyle.rightPadding verticalAlignment: Text.AlignVCenter } hoverEnabled: true } linphone-desktop-4.2.5/linphone-app/ui/modules/Common/Misc/000077500000000000000000000000001376717241300236225ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/ui/modules/Common/Misc/Borders.qml000066400000000000000000000034311376717241300257360ustar00rootroot00000000000000import QtQuick 2.7 // ============================================================================= // Alternative to rectangle border which is a limited feature. // Allow the use of different borders (size, color...) for each // rectangle side. // ============================================================================= Rectangle { property var borderColor property var borderWidth property color bottomColor: 'transparent' property color leftColor: 'transparent' property color rightColor: 'transparent' property color topColor: 'transparent' property int bottomWidth: 0 property int leftWidth: 0 property int rightWidth: 0 property int topWidth: 0 default property alias _content: content.data color: 'transparent' Rectangle { id: bottomBorder anchors.bottom: parent.bottom color: borderColor != null ? borderColor : bottomColor height: borderWidth != null ? borderWidth : bottomWidth width: parent.width } Rectangle { id: leftBorder anchors.left: parent.left color: borderColor != null ? borderColor : leftColor height: parent.height width: borderWidth != null ? borderWidth : leftWidth } Rectangle { id: rightBorder anchors.right: parent.right color: borderColor != null ? borderColor : rightColor height: parent.height width: borderWidth != null ? borderWidth : rightWidth } Rectangle { id: topBorder anchors.top: parent.top color: borderColor != null ? borderColor : topColor height: borderWidth != null ? borderWidth : topWidth width: parent.width } Item { id: content anchors { fill: parent bottomMargin: bottomBorder.height leftMargin: leftBorder.width rightMargin: rightBorder.width topMargin: topBorder.height } } } linphone-desktop-4.2.5/linphone-app/ui/modules/Common/Misc/ForceScrollBar.qml000066400000000000000000000015111376717241300271750ustar00rootroot00000000000000import QtQuick 2.7 import QtQuick.Controls 2.2 import Common.Styles 1.0 // ============================================================================= // A simple custom vertical scrollbar. // ============================================================================= ScrollBar { id: scrollBar background: Rectangle { anchors.fill: parent color: ForceScrollBarStyle.backgroundColor } contentItem: Rectangle { color: scrollBar.pressed ? ForceScrollBarStyle.color.pressed : (scrollBar.hovered ? ForceScrollBarStyle.color.hovered : ForceScrollBarStyle.color.normal ) implicitHeight: ForceScrollBarStyle.contentItem.implicitHeight implicitWidth: ForceScrollBarStyle.contentItem.implicitWidth radius: ForceScrollBarStyle.contentItem.radius } hoverEnabled: true } linphone-desktop-4.2.5/linphone-app/ui/modules/Common/Misc/Paned.qml000066400000000000000000000204321376717241300253650ustar00rootroot00000000000000import QtQuick 2.7 import Common 1.0 import Common.Styles 1.0 import Utils 1.0 // ============================================================================= // // Paned is one container divided in two areas. // The division between the areas can be modified with a handle. // // Each area can have a fixed or dynamic minimum width. // See `minimumLeftLimit` and `minimumRightLimit` attributes. // // Note: Paned supports too `maximumLeftLimit` and // `maximumRightLimit`. // // To create a dynamic minimum width, it's necessary to give // a percentage to `minmimumLeftLimit` or `minimumRightLimit` like: // `minimumLeftLimit: '66%'`. // The percentage is relative to the container width. // // ============================================================================= Item { id: container // --------------------------------------------------------------------------- property alias childA: contentA.data property alias childAItem: contentA property alias childB: contentB.data property bool defaultClosed: false property bool resizeAInPriority: false property int closingEdge: Qt.LeftEdge // `LeftEdge` or `RightEdge`. property int defaultChildAWidth // User limits: string or int values. // By default: no limits. property var maximumLeftLimit property var maximumRightLimit property var minimumLeftLimit: 0 property var minimumRightLimit: 0 property bool _isClosed // Internal limits. property var _maximumLeftLimit property var _maximumRightLimit property var _minimumLeftLimit property var _minimumRightLimit // --------------------------------------------------------------------------- // Public functions. // --------------------------------------------------------------------------- function isClosed () { return _isClosed } function open () { if (_isClosed) { openingTransition.running = true } } function close () { if (!_isClosed) { _close() } } // --------------------------------------------------------------------------- // Private functions. // --------------------------------------------------------------------------- function _getLimitValue (limit) { if (limit == null) { return } return limit.isDynamic ? width * limit.value : limit.value } function _parseLimit (limit) { if (limit == null) { return } if (Utils.isString(limit)) { var arr = limit.split('%') if (arr[1] === '') { return { isDynamic: true, value: +arr[0] / 100 } } } return { value: limit } } function _applyLimits () { var maximumLeftLimit = _getLimitValue(_maximumLeftLimit) var maximumRightLimit = _getLimitValue(_maximumRightLimit) var minimumLeftLimit = _getLimitValue(_minimumLeftLimit) var minimumRightLimit = _getLimitValue(_minimumRightLimit) var theoreticalBWidth = container.width - contentA.width - handle.width // If closed, set correctly the handle position to left or right. if (_isClosed) { contentA.width = (closingEdge !== Qt.LeftEdge) ? container.width - handle.width : 0 } // width(A) < minimum width(A). else if (contentA.width < minimumLeftLimit) { contentA.width = minimumLeftLimit } // width(A) > maximum width(A). else if (maximumLeftLimit != null && contentA.width > maximumLeftLimit) { contentA.width = maximumLeftLimit } // width(B) < minimum width(B). else if (theoreticalBWidth < minimumRightLimit) { contentA.width = container.width - handle.width - minimumRightLimit } // width(B) > maximum width(B). else if (maximumRightLimit != null && theoreticalBWidth > maximumRightLimit) { contentA.width = container.width - handle.width - maximumRightLimit } else if (resizeAInPriority) { contentA.width = container.width - handle.width - contentB.width } } // --------------------------------------------------------------------------- function _applyLimitsOnUserMove (offset) { var minimumRightLimit = _getLimitValue(_minimumRightLimit) var minimumLeftLimit = _getLimitValue(_minimumLeftLimit) // One area is closed. if (_isClosed) { if (closingEdge === Qt.LeftEdge) { if (offset > minimumLeftLimit / 2) { _open() } } else { if (-offset > minimumRightLimit / 2) { _open() } } return } // Check limits. var maximumLeftLimit = _getLimitValue(_maximumLeftLimit) var maximumRightLimit = _getLimitValue(_maximumRightLimit) var theoreticalBWidth = container.width - offset - contentA.width - handle.width // width(A) < minimum width(A). if (contentA.width + offset < minimumLeftLimit) { contentA.width = minimumLeftLimit if (closingEdge === Qt.LeftEdge && -offset > minimumLeftLimit / 2) { if (_isClosed) { _open() } else { _close() } } } // width(A) > maximum width(A). else if (maximumLeftLimit != null && contentA.width + offset > maximumLeftLimit) { contentA.width = maximumLeftLimit } // width(B) < minimum width(B). else if (theoreticalBWidth < minimumRightLimit) { contentA.width = container.width - handle.width - minimumRightLimit if (closingEdge !== Qt.LeftEdge && offset > minimumRightLimit / 2) { if (_isClosed) { _open() } else { _close() } } } // width(B) > maximum width(B). else if (maximumRightLimit != null && theoreticalBWidth > maximumRightLimit) { contentA.width = container.width - handle.width - maximumRightLimit } // Resize A/B. else { contentA.width = contentA.width + offset } } // --------------------------------------------------------------------------- function _open () { _isClosed = false _applyLimits() } function _close () { _isClosed = true closingTransition.running = true } function _inverseClosingState () { if (!_isClosed) { // Save state and close. _close() } else { // Restore old state. openingTransition.running = true } } function _isVisible (edge) { return ( !_isClosed || openingTransition.running || closingTransition.running ) || closingEdge !== edge } // --------------------------------------------------------------------------- onWidthChanged: _applyLimits() Component.onCompleted: { // Unable to modify these properties after creation. // It's a desired choice. _maximumLeftLimit = _parseLimit(maximumLeftLimit) _maximumRightLimit = _parseLimit(maximumRightLimit) _minimumLeftLimit = _parseLimit(minimumLeftLimit) _minimumRightLimit = _parseLimit(minimumRightLimit) contentA.width = (defaultChildAWidth == null) ? _getLimitValue(_minimumLeftLimit) : defaultChildAWidth _isClosed = defaultClosed } Item { id: contentA height: parent.height visible: _isVisible(Qt.LeftEdge) } MouseArea { id: handle property int _mouseStart anchors.left: contentA.right cursorShape: Qt.SplitHCursor height: parent.height hoverEnabled: true width: PanedStyle.handle.width onDoubleClicked: _inverseClosingState() onMouseXChanged: pressed && _applyLimitsOnUserMove(mouseX - _mouseStart) onPressed: _mouseStart = mouseX Rectangle { anchors.fill: parent color: parent.pressed ? PanedStyle.handle.color.pressed : (parent.containsMouse ? PanedStyle.handle.color.hovered : PanedStyle.handle.color.normal ) } } Item { id: contentB anchors.left: handle.right height: parent.height visible: _isVisible(Qt.RightEdge) width: container.width - contentA.width - handle.width } PropertyAnimation { id: openingTransition duration: PanedStyle.transitionDuration property: 'width' target: contentA to: closingEdge === Qt.LeftEdge ? minimumLeftLimit : container.width - minimumRightLimit - handle.width onRunningChanged: !running && _open() } PropertyAnimation { id: closingTransition duration: PanedStyle.transitionDuration property: 'width' target: contentA to: closingEdge === Qt.LeftEdge ? 0 : container.width - handle.width } } linphone-desktop-4.2.5/linphone-app/ui/modules/Common/Popup/000077500000000000000000000000001376717241300240325ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/ui/modules/Common/Popup/DesktopPopup.qml000066400000000000000000000045141376717241300272060ustar00rootroot00000000000000import QtQuick 2.7 import QtQuick.Window 2.2 import QtQuick.Controls 2.2 import QtQuick.Layouts 1.3 import Qt.labs.platform 1.0 import Common.Styles 1.0 // ============================================================================= Item { id: wrapper objectName: '__internalWrapper' // --------------------------------------------------------------------------- property alias popupX: window.x property alias popupY: window.y property bool requestActivate: false property int flags: Qt.SplashScreen readonly property alias popupWidth: window.width readonly property alias popupHeight: window.height default property alias _content: content.data property bool _isOpen: false signal isOpened() signal isClosed() signal dataChanged() on_ContentChanged: dataChanged(_content) // --------------------------------------------------------------------------- function open () { _isOpen = true; isOpened(); } function close () { _isOpen = false isClosed() } // --------------------------------------------------------------------------- // No size, no position. height: 0 width: 0 visible:true Window { id: window objectName: '__internalWindow' property bool isFrameLess : false; property bool showAsTool : false // Don't use Popup for flags : it could lead to error in geometry. On Mac, Using Tool ensure to have the Window on Top and fullscreen independant flags: Qt.BypassWindowManagerHint | (showAsTool?Qt.Tool:Qt.WindowStaysOnTopHint) | Qt.Window | Qt.FramelessWindowHint; opacity: 1.0 height: _content[0] != null ? _content[0].height : 0 width: _content[0] != null ? _content[0].width : 0 visible:true Item { id: content anchors.fill:parent property var $parent: wrapper } } // --------------------------------------------------------------------------- states: State { name: 'opening' when: _isOpen PropertyChanges { opacity: 1.0 target: window } } transitions: [ Transition { from: '' to: 'opening' ScriptAction { script: { if (wrapper.requestActivate) { window.requestActivate() } } } }, Transition { from: '*' to: '' ScriptAction { script: window.close() } } ] } linphone-desktop-4.2.5/linphone-app/ui/modules/Common/Popup/Popup.qml000066400000000000000000000037251376717241300256570ustar00rootroot00000000000000import QtQuick 2.7 import QtQuick.Controls 2.2 as Controls import Common.Styles 1.0 import Utils 1.0 // ============================================================================= Item { id: wrapper // Optionnal parameters, set the position of popup relative to this item. property var relativeTo property int relativeX: 0 property int relativeY: 0 default property alias _content: popup.contentItem property alias closePolicy : popup.closePolicy // --------------------------------------------------------------------------- signal closed signal opened // --------------------------------------------------------------------------- function open () { if (popup.visible) { return } if (relativeTo) { var parent = Utils.getTopParent(this) popup.x = Qt.binding(function () { return relativeTo ? relativeTo.mapToItem(null, relativeX, relativeY).x : 0 }) popup.y = Qt.binding(function () { return relativeTo ? relativeTo.mapToItem(null, relativeX, relativeY).y : 0 }) } else { popup.x = Qt.binding(function () { return x }) popup.y = Qt.binding(function () { return y }) } popup.open() } function close () { if (!popup.visible) { return } popup.x = 0 popup.y = 0 popup.close() } // --------------------------------------------------------------------------- visible: false // --------------------------------------------------------------------------- Controls.Popup { id: popup height: wrapper._content.height width: wrapper._content.width background: Rectangle { color: PopupStyle.backgroundColor height: popup.height width: popup.width layer { enabled: true effect: PopupShadow {} } } padding: 0 Component.onCompleted: parent = Utils.getTopParent(this) onClosed: wrapper.closed() onOpened: wrapper.opened() } } linphone-desktop-4.2.5/linphone-app/ui/modules/Common/Popup/PopupShadow.qml000066400000000000000000000005551376717241300270230ustar00rootroot00000000000000import QtGraphicalEffects 1.0 import Common.Styles 1.0 // ============================================================================= DropShadow { color: PopupStyle.shadow.color horizontalOffset: PopupStyle.shadow.horizontalOffset radius: PopupStyle.shadow.radius samples: PopupStyle.shadow.samples verticalOffset: PopupStyle.shadow.verticalOffset } linphone-desktop-4.2.5/linphone-app/ui/modules/Common/Styles/000077500000000000000000000000001376717241300242125ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/ui/modules/Common/Styles/Animations/000077500000000000000000000000001376717241300263145ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/ui/modules/Common/Styles/Animations/BusyIndicatorStyle.qml000066400000000000000000000003571376717241300326340ustar00rootroot00000000000000pragma Singleton import QtQml 2.2 import Colors 1.0 // ============================================================================= QtObject { property color color: Colors.i property int duration: 1250 property int nSpheres: 6 } linphone-desktop-4.2.5/linphone-app/ui/modules/Common/Styles/Dialog/000077500000000000000000000000001376717241300254115ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/ui/modules/Common/Styles/Dialog/DialogStyle.qml000066400000000000000000000014571376717241300303530ustar00rootroot00000000000000pragma Singleton import QtQml 2.2 import Colors 1.0 import Units 1.0 // ============================================================================= QtObject { property color color: Colors.k property QtObject buttons: QtObject { property int bottomMargin: 15 property int leftMargin: 50 property int spacing: 20 property int topMargin: 15 } property QtObject confirmDialog: QtObject { property int height: 200 property int width: 400 } property QtObject content: QtObject { property int leftMargin: 25 property int rightMargin: 25 } property QtObject description: QtObject { property color color: Colors.j property int leftMargin: 50 property int pointSize: Units.dp * 11 property int rightMargin: 50 property int verticalMargin: 25 } } linphone-desktop-4.2.5/linphone-app/ui/modules/Common/Styles/Form/000077500000000000000000000000001376717241300251155ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/ui/modules/Common/Styles/Form/ActionBarStyle.qml000066400000000000000000000002341376717241300305120ustar00rootroot00000000000000pragma Singleton import QtQml 2.2 // ============================================================================= QtObject { property int spacing: 8 } linphone-desktop-4.2.5/linphone-app/ui/modules/Common/Styles/Form/Buttons/000077500000000000000000000000001376717241300265535ustar00rootroot00000000000000AbstractTextButtonStyle.qml000066400000000000000000000005531376717241300340370ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/ui/modules/Common/Styles/Form/Buttonspragma Singleton import QtQuick 2.7 import Units 1.0 // ============================================================================= QtObject { property QtObject background: QtObject { property int height: 30 property int radius: 4 property int width: 160 } property QtObject text: QtObject { property int pointSize: Units.dp * 8 } } linphone-desktop-4.2.5/linphone-app/ui/modules/Common/Styles/Form/Buttons/ExclusiveButtonsStyle.qml000066400000000000000000000006541376717241300336420ustar00rootroot00000000000000pragma Singleton import QtQml 2.2 import Colors 1.0 // ============================================================================= QtObject { property int buttonsSpacing: 8 property QtObject button: QtObject { property QtObject color: QtObject { property color hovered: Colors.n property color normal: Colors.c property color pressed: Colors.i property color selected: Colors.g } } } linphone-desktop-4.2.5/linphone-app/ui/modules/Common/Styles/Form/Buttons/FileChooserButtonStyle.qml000066400000000000000000000007271376717241300337130ustar00rootroot00000000000000pragma Singleton import QtQml 2.2 import Colors 1.0 // ============================================================================= QtObject { property QtObject tools: QtObject { property int width: 30 property QtObject button: QtObject { property int iconSize: 16 property QtObject color: QtObject { property color hovered: Colors.c property color normal: Colors.f property color pressed: Colors.c } } } } linphone-desktop-4.2.5/linphone-app/ui/modules/Common/Styles/Form/Buttons/SmallButtonStyle.qml000066400000000000000000000011441376717241300325530ustar00rootroot00000000000000pragma Singleton import QtQml 2.2 import Colors 1.0 import Units 1.0 // ============================================================================= QtObject { property int leftPadding: 5 property int rightPadding: 5 property QtObject background: QtObject { property int height: 22 property int radius: 10 property QtObject color: QtObject { property color hovered: Colors.c property color normal: Colors.f property color pressed: Colors.i } } property QtObject text: QtObject { property color color: Colors.q property int pointSize: Units.dp * 8 } } linphone-desktop-4.2.5/linphone-app/ui/modules/Common/Styles/Form/Buttons/TextButtonAStyle.qml000066400000000000000000000010401376717241300325230ustar00rootroot00000000000000pragma Singleton import QtQml 2.2 import Colors 1.0 // ============================================================================= QtObject { property QtObject backgroundColor: QtObject { property color disabled: Colors.o property color hovered: Colors.j property color normal: Colors.g property color pressed: Colors.i } property QtObject textColor: QtObject { property color disabled: Colors.q property color hovered: Colors.q property color normal: Colors.q property color pressed: Colors.q } } linphone-desktop-4.2.5/linphone-app/ui/modules/Common/Styles/Form/Buttons/TextButtonBStyle.qml000066400000000000000000000010421376717241300325260ustar00rootroot00000000000000pragma Singleton import QtQml 2.2 import Colors 1.0 // ============================================================================= QtObject { property QtObject backgroundColor: QtObject { property color disabled: Colors.i30 property color hovered: Colors.b property color normal: Colors.i property color pressed: Colors.m } property QtObject textColor: QtObject { property color disabled: Colors.q property color hovered: Colors.q property color normal: Colors.q property color pressed: Colors.q } } linphone-desktop-4.2.5/linphone-app/ui/modules/Common/Styles/Form/CheckBoxTextStyle.qml000066400000000000000000000006301376717241300312030ustar00rootroot00000000000000pragma Singleton import QtQml 2.2 import Colors 1.0 import Units 1.0 // ============================================================================= QtObject { property int pointSize: Units.dp * 10 property int radius: 3 property int size: 18 property QtObject color: QtObject { property color pressed: Colors.i property color hovered: Colors.h property color normal: Colors.g } } linphone-desktop-4.2.5/linphone-app/ui/modules/Common/Styles/Form/ComboBoxStyle.qml000066400000000000000000000014761376717241300303710ustar00rootroot00000000000000pragma Singleton import QtQml 2.2 import Colors 1.0 import Units 1.0 // ============================================================================= QtObject { property QtObject background: QtObject { property int height: 36 property int iconSize: 10 property int radius: 4 property int width: 200 property QtObject border: QtObject { property color color: Colors.c property int width: 1 } property QtObject color: QtObject { property color normal: Colors.q property color readOnly: Colors.e } } property QtObject contentItem: QtObject { property int iconSize: 20 property int leftMargin: 10 property int spacing: 5 property QtObject text: QtObject { property color color: Colors.d property int pointSize: Units.dp * 10 } } } linphone-desktop-4.2.5/linphone-app/ui/modules/Common/Styles/Form/CommonItemDelegateStyle.qml000066400000000000000000000013341376717241300323540ustar00rootroot00000000000000pragma Singleton import QtQml 2.2 import Colors 1.0 import Units 1.0 // ============================================================================= QtObject { property QtObject color: QtObject { property color hovered: Colors.o property color normal: Colors.q } property QtObject contentItem: QtObject { property int iconSize: 20 property int spacing: 5 property QtObject text: QtObject { property color color: Colors.d property int pointSize: Units.dp * 10 } } property QtObject indicator: QtObject { property color color: Colors.i property int width: 5 } property QtObject separator: QtObject { property color color: Colors.c property int height: 1 } } linphone-desktop-4.2.5/linphone-app/ui/modules/Common/Styles/Form/DroppableTextAreaStyle.qml000066400000000000000000000012231376717241300322150ustar00rootroot00000000000000pragma Singleton import QtQml 2.2 import Colors 1.0 import Units 1.0 // ============================================================================= QtObject { property color backgroundColor: Colors.q property QtObject fileChooserButton: QtObject { property int margins: 6 property int size: 20 } property QtObject hoverContent: QtObject { property color backgroundColor: Colors.q property QtObject text: QtObject { property color color: Colors.i property int pointSize: Units.dp * 11 } } property QtObject text: QtObject { property color color: Colors.d property int pointSize: Units.dp * 10 } } linphone-desktop-4.2.5/linphone-app/ui/modules/Common/Styles/Form/Fields/000077500000000000000000000000001376717241300263235ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/ui/modules/Common/Styles/Form/Fields/NumericFieldStyle.qml000066400000000000000000000010441376717241300324240ustar00rootroot00000000000000pragma Singleton import QtQml 2.2 import Colors 1.0 import Units 1.0 // ============================================================================= QtObject { property QtObject tools: QtObject { property int width: 20 property QtObject button: QtObject { property QtObject color: QtObject { property color normal: Colors.f property color pressed: Colors.c } property QtObject text: QtObject { property color color: Colors.d property int pointSize: Units.dp * 9 } } } } linphone-desktop-4.2.5/linphone-app/ui/modules/Common/Styles/Form/Fields/TextAreaFieldStyle.qml000066400000000000000000000012521376717241300325400ustar00rootroot00000000000000pragma Singleton import QtQml 2.2 import Colors 1.0 import Units 1.0 // ============================================================================= QtObject { property QtObject background: QtObject { property int height: 36 property int width: 200 property int radius: 4 property QtObject border: QtObject { property color color: Colors.c property int width: 1 } property QtObject color: QtObject { property color normal: Colors.q property color readOnly: Colors.e } } property QtObject text: QtObject { property color color: Colors.d property int pointSize: Units.dp * 10 property int padding: 8 } } linphone-desktop-4.2.5/linphone-app/ui/modules/Common/Styles/Form/Fields/TextFieldStyle.qml000066400000000000000000000014731376717241300317540ustar00rootroot00000000000000pragma Singleton import QtQml 2.2 import Colors 1.0 import Units 1.0 // ============================================================================= QtObject { property QtObject background: QtObject { property int height: 36 property int width: 200 property int radius: 4 property QtObject border: QtObject { property QtObject color: QtObject { property color error: Colors.error property color normal: Colors.c property color selected: Colors.i } property int width: 1 } property QtObject color: QtObject { property color normal: Colors.q property color readOnly: Colors.e } } property QtObject text: QtObject { property color color: Colors.d property int pointSize: Units.dp * 10 property int rightPadding: 10 } } linphone-desktop-4.2.5/linphone-app/ui/modules/Common/Styles/Form/ListFormStyle.qml000066400000000000000000000013101376717241300304030ustar00rootroot00000000000000pragma Singleton import QtQml 2.2 import Colors 1.0 import Units 1.0 // ============================================================================= QtObject { property int lineHeight: 35 property QtObject value: QtObject { property QtObject placeholder: QtObject { property color color: Colors.n property int pointSize: Units.dp * 10 } property QtObject text: QtObject { property int padding: 10 } } property QtObject titleArea: QtObject { property int spacing: 10 property int iconSize: 18 property QtObject text: QtObject { property color color: Colors.j property int pointSize: Units.dp * 9 property int width: 130 } } } linphone-desktop-4.2.5/linphone-app/ui/modules/Common/Styles/Form/Placements/000077500000000000000000000000001376717241300272105ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/ui/modules/Common/Styles/Form/Placements/FormHGroupStyle.qml000066400000000000000000000006761376717241300330050ustar00rootroot00000000000000pragma Singleton import QtQml 2.2 import Colors 1.0 import Units 1.0 // ============================================================================= QtObject { property int spacing: 20 property QtObject content: QtObject { property int maxWidth: 400 } property QtObject legend: QtObject { property color color: Colors.j property int pointSize: Units.dp * 10 property int height: 36 property int width: 200 } } linphone-desktop-4.2.5/linphone-app/ui/modules/Common/Styles/Form/Placements/FormLineStyle.qml000066400000000000000000000002351376717241300324570ustar00rootroot00000000000000pragma Singleton import QtQml 2.2 // ============================================================================= QtObject { property int spacing: 20 } linphone-desktop-4.2.5/linphone-app/ui/modules/Common/Styles/Form/Placements/FormStyle.qml000066400000000000000000000010371376717241300316500ustar00rootroot00000000000000pragma Singleton import QtQml 2.2 import Colors 1.0 import Units 1.0 // ============================================================================= QtObject { property int spacing: 10 property QtObject header: QtObject { property int bottomMargin: 5 property int spacing: 5 property QtObject separator: QtObject { property color color: Colors.i property int height: 2 } property QtObject title: QtObject { property color color: Colors.i property int pointSize: Units.dp * 12 } } } linphone-desktop-4.2.5/linphone-app/ui/modules/Common/Styles/Form/Placements/FormTableLineStyle.qml000066400000000000000000000002351376717241300334270ustar00rootroot00000000000000pragma Singleton import QtQml 2.2 // ============================================================================= QtObject { property int spacing: 20 } linphone-desktop-4.2.5/linphone-app/ui/modules/Common/Styles/Form/Placements/FormTableStyle.qml000066400000000000000000000007021376717241300326160ustar00rootroot00000000000000pragma Singleton import QtQml 2.2 import Colors 1.0 import Units 1.0 // ============================================================================= QtObject { property int spacing: 10 property QtObject entry: QtObject { property int height: 36 property int width: 200 property int maxWidth: 400 property QtObject text: QtObject { property color color: Colors.j property int pointSize: Units.dp * 10 } } } linphone-desktop-4.2.5/linphone-app/ui/modules/Common/Styles/Form/Placements/FormVGroupStyle.qml000066400000000000000000000010351376717241300330110ustar00rootroot00000000000000pragma Singleton import QtQml 2.2 import Colors 1.0 import Units 1.0 // ============================================================================= QtObject { property int spacing: 5 property QtObject content: QtObject { property int maxWidth: 400 } property QtObject error: QtObject { property color color: Colors.error property int pointSize: Units.dp * 10 property int height: 11 } property QtObject legend: QtObject { property color color: Colors.j property int pointSize: Units.dp * 10 } } linphone-desktop-4.2.5/linphone-app/ui/modules/Common/Styles/Form/SearchBoxStyle.qml000066400000000000000000000002741376717241300305320ustar00rootroot00000000000000pragma Singleton import QtQml 2.2 import Colors 1.0 // ============================================================================= QtObject { property color shadowColor: Colors.l } linphone-desktop-4.2.5/linphone-app/ui/modules/Common/Styles/Form/SliderStyle.qml000066400000000000000000000015321376717241300300740ustar00rootroot00000000000000pragma Singleton import QtQml 2.2 import Colors 1.0 // ============================================================================= QtObject { property QtObject background: QtObject { property color color: Colors.c property int height: 4 property int radius: 2 property int width: 200 property QtObject content: QtObject { property color color: Colors.m property int radius: 2 } } property QtObject handle: QtObject { property int height: 16 property int radius: 13 property int width: 16 property QtObject border: QtObject { property QtObject color: QtObject { property color normal: Colors.c property color pressed: Colors.c } } property QtObject color: QtObject { property color normal: Colors.e property color pressed: Colors.f } } } linphone-desktop-4.2.5/linphone-app/ui/modules/Common/Styles/Form/SwitchStyle.qml000066400000000000000000000023241376717241300301130ustar00rootroot00000000000000pragma Singleton import QtQml 2.2 import Colors 1.0 // ============================================================================= QtObject { property QtObject animation: QtObject { property int duration: 200 } property QtObject indicator: QtObject { property int height: 18 property int radius: 10 property int width: 48 property QtObject border: QtObject { property QtObject color: QtObject { property color checked: Colors.i property color disabled: Colors.c property color normal: Colors.c } } property QtObject color: QtObject { property color checked: Colors.i property color disabled: Colors.e property color normal: Colors.q } } property QtObject sphere: QtObject { property int size: 22 property QtObject border: QtObject { property QtObject color: QtObject { property color checked: Colors.i property color disabled: Colors.c property color normal: Colors.n property color pressed: Colors.n } } property QtObject color: QtObject { property color disabled: Colors.e property color pressed: Colors.c property color normal: Colors.q } } } linphone-desktop-4.2.5/linphone-app/ui/modules/Common/Styles/Form/Tab/000077500000000000000000000000001376717241300256235ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/ui/modules/Common/Styles/Form/Tab/TabButtonStyle.qml000066400000000000000000000016321376717241300312630ustar00rootroot00000000000000pragma Singleton import QtQml 2.2 import Colors 1.0 import Units 1.0 // ============================================================================= QtObject { property int spacing: 8 property QtObject backgroundColor: QtObject { property color disabled: Colors.i30 property color hovered: Colors.b property color normal: Colors.i property color pressed: Colors.m property color selected: Colors.k } property QtObject icon: QtObject { property int size: 20 } property QtObject text: QtObject { property int pointSize: Units.dp * 9 property int height: 40 property int leftPadding: 10 property int rightPadding: 10 property QtObject color: QtObject { property color disabled: Colors.q property color hovered: Colors.q property color normal: Colors.q property color pressed: Colors.q property color selected: Colors.i } } } linphone-desktop-4.2.5/linphone-app/ui/modules/Common/Styles/Form/Tab/TabContainerStyle.qml000066400000000000000000000006351376717241300317340ustar00rootroot00000000000000pragma Singleton import QtQml 2.2 import Colors 1.0 // ============================================================================= QtObject { property color color: Colors.k property int bottomMargin: 30 property int leftMargin: 30 property int rightMargin: 40 property int topMargin: 30 property QtObject separator: QtObject { property int height: 2 property color color: Colors.f } } linphone-desktop-4.2.5/linphone-app/ui/modules/Common/Styles/Form/TransparentTextInputStyle.qml000066400000000000000000000011261376717241300330370ustar00rootroot00000000000000pragma Singleton import QtQml 2.2 import Colors 1.0 import Units 1.0 // ============================================================================= QtObject { property color backgroundColor: Colors.f property int iconSize: 12 property int padding: 10 property QtObject placeholder: QtObject { property color color: Colors.n property int pointSize: Units.dp * 10 } property QtObject text: QtObject { property int pointSize: Units.dp * 10 property QtObject color: QtObject { property color focused: Colors.l property color normal: Colors.d } } } linphone-desktop-4.2.5/linphone-app/ui/modules/Common/Styles/Indicators/000077500000000000000000000000001376717241300263115ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/ui/modules/Common/Styles/Indicators/VuMeterStyle.qml000066400000000000000000000014761376717241300314440ustar00rootroot00000000000000pragma Singleton import QtQml 2.2 import Colors 1.0 // ============================================================================= QtObject { property int height: 40 property int width: 5 property QtObject high: QtObject { property QtObject background: QtObject { property QtObject color: QtObject { property color disabled: Colors.o property color enabled: Colors.n } } property QtObject contentItem: QtObject { property color color: Colors.b } } property QtObject low: QtObject { property QtObject background: QtObject { property QtObject color: QtObject { property color disabled: Colors.o property color enabled: Colors.n } } property QtObject contentItem: QtObject { property color color: Colors.j } } } linphone-desktop-4.2.5/linphone-app/ui/modules/Common/Styles/Menus/000077500000000000000000000000001376717241300253015ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/ui/modules/Common/Styles/Menus/ApplicationMenuStyle.qml000066400000000000000000000016621376717241300321320ustar00rootroot00000000000000pragma Singleton import QtQml 2.2 import Colors 1.0 import Units 1.0 // ============================================================================= QtObject { property int spacing: 1 property color backgroundColor: Colors.n property QtObject entry: QtObject { property int iconSize: 24 property int leftMargin: 20 property int rightMargin: 20 property int spacing: 18 property QtObject color: QtObject { property color hovered: Colors.h property color normal: Colors.g property color pressed: Colors.i property color selected: Colors.j } property QtObject indicator: QtObject { property color color: Colors.i property int width: 5 } property QtObject text: QtObject { property int pointSize: Units.dp * 11 property QtObject color: QtObject { property color normal: Colors.q50 property color selected: Colors.q } } } } linphone-desktop-4.2.5/linphone-app/ui/modules/Common/Styles/Menus/DropDownStaticMenuStyle.qml000066400000000000000000000011141376717241300325630ustar00rootroot00000000000000pragma Singleton import QtQml 2.2 import Colors 1.0 import Units 1.0 // ============================================================================= QtObject { property int spacing: 1 property QtObject entry: QtObject { property int leftMargin: 18 property int rightMargin: 8 property QtObject color: QtObject { property color hovered: Colors.j property color normal: Colors.g property color pressed: Colors.i } property QtObject text: QtObject { property color color: Colors.q property int pointSize: Units.dp * 9 } } } linphone-desktop-4.2.5/linphone-app/ui/modules/Common/Styles/Menus/MenuItemStyle.qml000066400000000000000000000012461376717241300305630ustar00rootroot00000000000000pragma Singleton import QtQml 2.2 import Colors 1.0 import Units 1.0 // ============================================================================= QtObject { property int leftPadding: 5 property int rightPadding: 5 property QtObject background: QtObject { property int height: 30 property QtObject color: QtObject { property color hovered: Colors.o property color normal: Colors.q property color pressed: Colors.o } } property QtObject text: QtObject { property int pointSize: Units.dp * 10 property QtObject color: QtObject { property color enabled: Colors.j property color disabled: Colors.l50 } } } linphone-desktop-4.2.5/linphone-app/ui/modules/Common/Styles/Menus/MenuStyle.qml000066400000000000000000000003201376717241300277340ustar00rootroot00000000000000pragma Singleton import QtQml 2.2 import Colors 1.0 // ============================================================================= QtObject { property color color: Colors.q property int width: 130 } linphone-desktop-4.2.5/linphone-app/ui/modules/Common/Styles/Misc/000077500000000000000000000000001376717241300251055ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/ui/modules/Common/Styles/Misc/ForceScrollBarStyle.qml000066400000000000000000000007571376717241300315140ustar00rootroot00000000000000pragma Singleton import QtQml 2.2 import Colors 1.0 // ============================================================================= QtObject { property color backgroundColor: Colors.g20 property QtObject contentItem: QtObject { property int implicitHeight: 8 property int implicitWidth: 8 property int radius: 10 } property QtObject color: QtObject { property color hovered: Colors.h property color normal: Colors.g20 property color pressed: Colors.d } } linphone-desktop-4.2.5/linphone-app/ui/modules/Common/Styles/Misc/PanedStyle.qml000066400000000000000000000006451376717241300276750ustar00rootroot00000000000000pragma Singleton import QtQml 2.2 import Colors 1.0 // ============================================================================= QtObject { property int transitionDuration: 200 property QtObject handle: QtObject { property int width: 5 property QtObject color: QtObject { property color hovered: Colors.h property color normal: Colors.c property color pressed: Colors.d } } } linphone-desktop-4.2.5/linphone-app/ui/modules/Common/Styles/Popup/000077500000000000000000000000001376717241300253155ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/ui/modules/Common/Styles/Popup/PopupStyle.qml000066400000000000000000000006201376717241300301520ustar00rootroot00000000000000pragma Singleton import QtQml 2.2 import Colors 1.0 // ============================================================================= QtObject { property color backgroundColor: Colors.k property QtObject shadow: QtObject { property color color: Colors.l property int horizontalOffset: 2 property int radius: 10 property int samples: 15 property int verticalOffset: 2 } } linphone-desktop-4.2.5/linphone-app/ui/modules/Common/Styles/Tooltip/000077500000000000000000000000001376717241300256445ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/ui/modules/Common/Styles/Tooltip/TooltipStyle.qml000066400000000000000000000006721376717241300310370ustar00rootroot00000000000000pragma Singleton import QtQml 2.2 import Colors 1.0 import Units 1.0 // ============================================================================= QtObject { property color backgroundColor: Colors.g property color color: Colors.q property int arrowSize: 8 property int delay: 1000 property int pointSize: Units.dp * 9 property int margins: 8 property int padding: 4 property int radius: 4 property int minWidth: 130 } linphone-desktop-4.2.5/linphone-app/ui/modules/Common/Styles/Window/000077500000000000000000000000001376717241300254615ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/ui/modules/Common/Styles/Window/WindowStyle.qml000066400000000000000000000003561376717241300304700ustar00rootroot00000000000000pragma Singleton import QtQml 2.2 import Colors 1.0 // ============================================================================= QtObject { property QtObject transientWindow: QtObject { property color color: Colors.l80 } } linphone-desktop-4.2.5/linphone-app/ui/modules/Common/Styles/qmldir000066400000000000000000000055011376717241300254260ustar00rootroot00000000000000# See: https://wiki.qt.io/Qml_Styling module Common.Styles # Components styles ------------------------------------------------------------ singleton BusyIndicatorStyle 1.0 Animations/BusyIndicatorStyle.qml singleton DialogStyle 1.0 Dialog/DialogStyle.qml singleton ActionBarStyle 1.0 Form/ActionBarStyle.qml singleton CheckBoxTextStyle 1.0 Form/CheckBoxTextStyle.qml singleton ComboBoxStyle 1.0 Form/ComboBoxStyle.qml singleton DroppableTextAreaStyle 1.0 Form/DroppableTextAreaStyle.qml singleton ListFormStyle 1.0 Form/ListFormStyle.qml singleton SearchBoxStyle 1.0 Form/SearchBoxStyle.qml singleton SliderStyle 1.0 Form/SliderStyle.qml singleton SwitchStyle 1.0 Form/SwitchStyle.qml singleton CommonItemDelegateStyle 1.0 Form/CommonItemDelegateStyle.qml singleton TransparentTextInputStyle 1.0 Form/TransparentTextInputStyle.qml singleton AbstractTextButtonStyle 1.0 Form/Buttons/AbstractTextButtonStyle.qml singleton ExclusiveButtonsStyle 1.0 Form/Buttons/ExclusiveButtonsStyle.qml singleton FileChooserButtonStyle 1.0 Form/Buttons/FileChooserButtonStyle.qml singleton SmallButtonStyle 1.0 Form/Buttons/SmallButtonStyle.qml singleton TextButtonAStyle 1.0 Form/Buttons/TextButtonAStyle.qml singleton TextButtonBStyle 1.0 Form/Buttons/TextButtonBStyle.qml singleton NumericFieldStyle 1.0 Form/Fields/NumericFieldStyle.qml singleton TextAreaFieldStyle 1.0 Form/Fields/TextAreaFieldStyle.qml singleton TextFieldStyle 1.0 Form/Fields/TextFieldStyle.qml singleton FormHGroupStyle 1.0 Form/Placements/FormHGroupStyle.qml singleton FormLineStyle 1.0 Form/Placements/FormLineStyle.qml singleton FormStyle 1.0 Form/Placements/FormStyle.qml singleton FormTableLineStyle 1.0 Form/Placements/FormTableLineStyle.qml singleton FormTableStyle 1.0 Form/Placements/FormTableStyle.qml singleton FormVGroupStyle 1.0 Form/Placements/FormVGroupStyle.qml singleton TabButtonStyle 1.0 Form/Tab/TabButtonStyle.qml singleton TabContainerStyle 1.0 Form/Tab/TabContainerStyle.qml singleton VuMeterStyle 1.0 Indicators/VuMeterStyle.qml singleton ApplicationMenuStyle 1.0 Menus/ApplicationMenuStyle.qml singleton DropDownStaticMenuStyle 1.0 Menus/DropDownStaticMenuStyle.qml singleton MenuItemStyle 1.0 Menus/MenuItemStyle.qml singleton MenuStyle 1.0 Menus/MenuStyle.qml singleton ForceScrollBarStyle 1.0 Misc/ForceScrollBarStyle.qml singleton PanedStyle 1.0 Misc/PanedStyle.qml singleton PopupStyle 1.0 Popup/PopupStyle.qml singleton TooltipStyle 1.0 Tooltip/TooltipStyle.qml singleton WindowStyle 1.0 Window/WindowStyle.qml linphone-desktop-4.2.5/linphone-app/ui/modules/Common/Tooltip/000077500000000000000000000000001376717241300243615ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/ui/modules/Common/Tooltip/Tooltip.qml000066400000000000000000000071361376717241300265350ustar00rootroot00000000000000import QtQuick 2.7 as Core import QtQuick.Controls 2.2 as Core import Common 1.0 import Common.Styles 1.0 import Utils 1.0 // ============================================================================= Core.ToolTip { id: tooltip property var _edge: 'left' // --------------------------------------------------------------------------- function _getArrowHeightMargin () { Utils.assert( icon.height >= icon.implicitHeight, '`icon.height` must be lower than `icon.implicitHeight`.' ) return (icon.height - icon.implicitHeight) / 2 } function _getArrowWidthMargin () { Utils.assert( icon.width >= icon.implicitWidth, '`icon.width` must be lower than `icon.implicitWidth`.' ) return (icon.width - icon.implicitWidth) / 2 } function _getRelativeXArrowCenter () { return tooltip.parent.width / 2 - icon.width / 2 } function _getRelativeYArrowCenter () { return tooltip.parent.height / 2 - icon.height / 2 } function _setArrowEdge () { var a = container.mapToItem(null, 0, 0) var b = tooltip.parent.mapToItem(null, 0, 0) if (a.x + container.width < b.x) { _edge = 'left' } else if (a.x > b.x + container.width) { _edge = 'right' } else if (a.y + container.height < b.y) { _edge = 'top' } else if (a.y > b.y + b.height) { _edge = 'bottom' } else { // Unable to get the tooltip arrow position. _edge = null } } // Called when new image is loaded. (When the is edge is updated.) function _setArrowPosition () { var a = container.mapToItem(null, 0, 0) var b = tooltip.parent.mapToItem(null, 0, 0) if (_edge === 'left') { icon.x = container.width - TooltipStyle.margins - _getArrowWidthMargin() icon.y = b.y - a.y + _getRelativeYArrowCenter() } else if (_edge === 'right') { icon.x = container.width + TooltipStyle.margins + _getArrowWidthMargin() icon.y = b.y - a.y + _getRelativeYArrowCenter() } else if (_edge === 'top') { icon.x = b.x - a.x + _getRelativeXArrowCenter() icon.y = container.height - TooltipStyle.margins - _getArrowHeightMargin() } else if (_edge === 'bottom') { icon.x = b.x - a.x + _getRelativeXArrowCenter() icon.y = container.height + TooltipStyle.margins + _getArrowHeightMargin() } } // --------------------------------------------------------------------------- background: Core.Item { id: container layer { enabled: true effect: PopupShadow {} } Core.Rectangle { anchors { fill: parent margins: TooltipStyle.margins } color: TooltipStyle.backgroundColor radius: TooltipStyle.radius } // Do not use `Icon` component to access to `implicitHeight` // and `implicitWidth`. Core.Image { id: icon mipmap: Qt.platform.os === 'osx' fillMode: Core.Image.PreserveAspectFit height: TooltipStyle.arrowSize source: _edge ? Utils.resolveImageUri('tooltip_arrow_' + _edge) : '' sourceSize.height: height sourceSize.width: width visible: tooltip.visible && _edge width: TooltipStyle.arrowSize z: Constants.zMax onStatusChanged: status === Core.Image.Ready && _setArrowPosition() } } contentItem: Core.Text { id: text color: TooltipStyle.color font.pointSize: TooltipStyle.pointSize padding: TooltipStyle.padding + TooltipStyle.margins text: tooltip.text wrapMode: Core.Text.WordWrap width:parent.width elide:Core.Text.ElideRight } delay: TooltipStyle.delay onVisibleChanged: visible && _setArrowEdge() } linphone-desktop-4.2.5/linphone-app/ui/modules/Common/Tooltip/TooltipArea.qml000066400000000000000000000020571376717241300273230ustar00rootroot00000000000000import QtQuick 2.7 import Common 1.0 import Common.Styles 1.0 // ============================================================================= MouseArea { id: tooltipArea property alias text: tooltip.text property int delay: TooltipStyle.delay property bool force: false property var tooltipParent: parent property bool _visible: false property int hoveringCursor : Qt.ArrowCursor anchors.fill:parent hoverEnabled: true scrollGestureEnabled: true onContainsMouseChanged: _visible = containsMouse cursorShape: containsMouse ? hoveringCursor : Qt.ArrowCursor onPressed: mouse.accepted = false onWheel: { _visible = false wheel.accepted = false } Tooltip { id: tooltip delay: tooltipArea.delay parent: tooltipParent visible: _visible || force width: tooltipParent.width>TooltipStyle.minWidth?tooltipParent.width:TooltipStyle.minWidth timeout: -1 // Workaround to always display tooltip. onVisibleChanged: { if (!visible && force) { tooltip.visible = true } } } } linphone-desktop-4.2.5/linphone-app/ui/modules/Common/View/000077500000000000000000000000001376717241300236415ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/ui/modules/Common/View/ScrollableListView.qml000066400000000000000000000014531376717241300301300ustar00rootroot00000000000000import QtQuick 2.7 import QtQuick.Controls 2.2 import Common 1.0 // ============================================================================= ListView { id: view // --------------------------------------------------------------------------- ScrollBar.vertical: ForceScrollBar { id: vScrollBar onPressedChanged: pressed ? view.movementStarted() : view.movementEnded() } // --------------------------------------------------------------------------- boundsBehavior: Flickable.StopAtBounds clip: true contentWidth: width - vScrollBar.width spacing: 0 // --------------------------------------------------------------------------- // TODO: Find a solution at this bug => // https://bugreports.qt.io/browse/QTBUG-31573 // https://bugreports.qt.io/browse/QTBUG-49989 } linphone-desktop-4.2.5/linphone-app/ui/modules/Common/Window/000077500000000000000000000000001376717241300241765ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/ui/modules/Common/Window/ApplicationWindow.qml000066400000000000000000000017711376717241300303520ustar00rootroot00000000000000import QtQuick 2.7 import QtQuick.Controls 2.2 import 'Window.js' as Logic // ============================================================================= ApplicationWindow { id: window default property alias _content: content.data readonly property bool virtualWindowVisible: virtualWindow.active // --------------------------------------------------------------------------- signal attachedVirtualWindow signal detachedVirtualWindow // --------------------------------------------------------------------------- function attachVirtualWindow (component, properties, exitStatusHandler) { Logic.attachVirtualWindow.call(this, component, properties, exitStatusHandler) } function detachVirtualWindow () { Logic.detachVirtualWindow() } // --------------------------------------------------------------------------- Item { anchors.fill: parent Rectangle { id: content anchors.fill: parent } VirtualWindow { id: virtualWindow } } } linphone-desktop-4.2.5/linphone-app/ui/modules/Common/Window/VirtualWindow.qml000066400000000000000000000075461376717241300275430ustar00rootroot00000000000000import QtQuick 2.7 import QtQuick.Controls 2.5 import Common 1.0 import Common.Styles 1.0 import 'Window.js' as Logic // ============================================================================= StackView{ id:stackView anchors.fill: parent property var active : !stackView.empty visible:!stackView.empty function setContent(url, properties, exitStatusHandler){ var isEmpty = stackView.empty; if(properties && properties.virtualWindowHash){ var haveItem = stackView.find(function(item, index) { return item.sourceProperties && item.sourceProperties.virtualWindowHash && item.sourceProperties.virtualWindowHash == properties.virtualWindowHash; }); if( haveItem == null ){//Push new push(page, {"sourceUrl":url, "sourceProperties":properties, "exitStatusHandler":exitStatusHandler, "setData":true, "active":true}); }else{//Update fields haveItem.sourceProperties = properties; haveItem.exitStatusHandler = exitStatusHandler; } }else{ push(page, {"sourceUrl":url, "sourceProperties":properties, "exitStatusHandler":exitStatusHandler, "setData":true, "active":true}); } return isEmpty; } function unsetContent () { if(stackView.depth == 1) clear(); else pop(); return stackView.empty; } Component{ id:page Loader { id:mainLoader active:false property var sourceUrl property var sourceProperties property var exitStatusHandler property bool setData : false // USe this flag to update source data // --------------------------------------------------------------------------- sourceComponent:Component{ id:mainComponent Item{ id:rootContent property alias contentLoader:content.contentLoader anchors.fill: parent MouseArea { anchors.fill: parent hoverEnabled: true onWheel: wheel.accepted = true cursorShape: Qt.ArrowCursor } Rectangle { id: content property alias contentLoader:contentLoader anchors.fill: parent color: WindowStyle.transientWindow.color Loader{ id:contentLoader anchors.centerIn: parent property var setSourceData : setData onSetSourceDataChanged: if( setData) {// SetData is true : assign source with properties using QML functions if(sourceProperties) setSource(sourceUrl, sourceProperties); else setSource(sourceUrl); }else{source=undefined}// SetData is false : clean memory active:mainLoader.active onLoaded:{// When loaded, attach handlers to content item.exitStatus.connect(Logic.detachVirtualWindow) if (exitStatusHandler) { item.exitStatus.connect(exitStatusHandler) } } } } } } } } } linphone-desktop-4.2.5/linphone-app/ui/modules/Common/Window/Window.js000066400000000000000000000030351376717241300260040ustar00rootroot00000000000000/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ // ============================================================================= // Windows (qml) Logic. // ============================================================================= .import 'qrc:/ui/scripts/Utils/utils.js' as Utils // ============================================================================= // Create a dynamic component hover the main content of one window. // The object parameter must have a `exitStatus` signal which is used // at item destruction. // // The exit status handler is optional. function attachVirtualWindow (component, properties, exitStatusHandler) { virtualWindow.setContent(component, properties, exitStatusHandler); } function detachVirtualWindow () { if( virtualWindow.active) virtualWindow.unsetContent(); } linphone-desktop-4.2.5/linphone-app/ui/modules/Common/Window/Window.qml000066400000000000000000000017671376717241300261730ustar00rootroot00000000000000import QtQuick 2.7 import QtQuick.Window 2.2 import 'Window.js' as Logic // ============================================================================= Window { id: window default property alias _content: content.data readonly property bool virtualWindowVisible: virtualWindow.active //visible // --------------------------------------------------------------------------- signal attachedVirtualWindow signal detachedVirtualWindow // --------------------------------------------------------------------------- function attachVirtualWindow (component, properties, exitStatusHandler) { Logic.attachVirtualWindow.call(this, component, properties, exitStatusHandler) } function detachVirtualWindow () { Logic.detachVirtualWindow() } // --------------------------------------------------------------------------- Item { anchors.fill: parent Rectangle { id: content anchors.fill: parent } VirtualWindow { id: virtualWindow } } } linphone-desktop-4.2.5/linphone-app/ui/modules/Common/qmldir000066400000000000000000000072211376717241300241440ustar00rootroot00000000000000# ============================================================================== # Common's components to export. # ============================================================================== module Common # Constants -------------------------------------------------------------------- singleton Constants 1.0 Constants/Constants.qml # Components ------------------------------------------------------------------- BusyIndicator 1.0 Animations/BusyIndicator.qml ConfirmDialog 1.0 Dialog/ConfirmDialog.qml DialogPlus 1.0 Dialog/DialogPlus.qml ActionBar 1.0 Form/ActionBar.qml ActionButton 1.0 Form/ActionButton.qml ActionSwitch 1.0 Form/ActionSwitch.qml CheckBoxText 1.0 Form/CheckBoxText.qml ComboBox 1.0 Form/ComboBox.qml CommonItemDelegate 1.0 Form/CommonItemDelegate.qml DroppableTextArea 1.0 Form/DroppableTextArea.qml ListForm 1.0 Form/ListForm.qml ListItemSelector 1.0 Form/ListItemSelector.qml MouseArea 1.0 Form/MouseArea.qml SearchBox 1.0 Form/SearchBox.qml Slider 1.0 Form/Slider.qml StaticListForm 1.0 Form/StaticListForm.qml Switch 1.0 Form/Switch.qml TransparentTextInput 1.0 Form/TransparentTextInput.qml ExclusiveButtons 1.0 Form/Buttons/ExclusiveButtons.qml FileChooserButton 1.0 Form/Buttons/FileChooserButton.qml TextButtonA 1.0 Form/Buttons/TextButtonA.qml TextButtonB 1.0 Form/Buttons/TextButtonB.qml HexField 1.0 Form/Fields/HexField.qml NumericField 1.0 Form/Fields/NumericField.qml PasswordField 1.0 Form/Fields/PasswordField.qml PortField 1.0 Form/Fields/PortField.qml ScrollableListViewField 1.0 Form/Fields/ScrollableListViewField.qml TextAreaField 1.0 Form/Fields/TextAreaField.qml TextField 1.0 Form/Fields/TextField.qml Form 1.0 Form/Placements/Form.qml FormEmptyLine 1.0 Form/Placements/FormEmptyLine.qml FormGroup 1.0 Form/Placements/FormGroup.qml FormLine 1.0 Form/Placements/FormLine.qml FormTable 1.0 Form/Placements/FormTable.qml FormTableEntry 1.0 Form/Placements/FormTableEntry.qml FormTableLine 1.0 Form/Placements/FormTableLine.qml TabBar 1.0 Form/Tab/TabBar.qml TabButton 1.0 Form/Tab/TabButton.qml TabContainer 1.0 Form/Tab/TabContainer.qml DragBox 1.0 Helpers/DragBox.qml InvertedMouseArea 1.0 Helpers/InvertedMouseArea.qml Icon 1.0 Image/Icon.qml RoundedImage 1.0 Image/RoundedImage.qml VuMeter 1.0 Indicators/VuMeter.qml ApplicationMenu 1.0 Menus/ApplicationMenu.qml ApplicationMenuEntry 1.0 Menus/ApplicationMenuEntry.qml DropDownDynamicMenu 1.0 Menus/DropDownDynamicMenu.qml DropDownStaticMenu 1.0 Menus/DropDownStaticMenu.qml DropDownStaticMenuEntry 1.0 Menus/DropDownStaticMenuEntry.qml Menu 1.0 Menus/Menu.qml MenuItem 1.0 Menus/MenuItem.qml Borders 1.0 Misc/Borders.qml ForceScrollBar 1.0 Misc/ForceScrollBar.qml Paned 1.0 Misc/Paned.qml DesktopPopup 1.0 Popup/DesktopPopup.qml Popup 1.0 Popup/Popup.qml PopupShadow 1.0 Popup/PopupShadow.qml TooltipArea 1.0 Tooltip/TooltipArea.qml ToolTip 1.0 Tooltip/Tooltip.qml ScrollableListView 1.0 View/ScrollableListView.qml ApplicationWindow 1.0 Window/ApplicationWindow.qml Window 1.0 Window/Window.qml linphone-desktop-4.2.5/linphone-app/ui/modules/Konami/000077500000000000000000000000001376717241300227155ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/ui/modules/Konami/Konami.qml000066400000000000000000000042421376717241300246500ustar00rootroot00000000000000/* * Konami.qml * Copyright 2017-2018 Ronan Abhamon (https://github.com/Wescoeur) * * 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. */ import QtQuick 2.7 // ============================================================================= Item { id: konami property var code: [ Qt.Key_Up, Qt.Key_Up, Qt.Key_Down, Qt.Key_Down, Qt.Key_Left, Qt.Key_Right, Qt.Key_Left, Qt.Key_Right, Qt.Key_B, Qt.Key_A ] property int delay: 2000 signal triggered // --------------------------------------------------------------------------- Keys.forwardTo: core Timer { id: timer interval: konami.delay onTriggered: core.index = 0 } Item { id: core property int index: 0 anchors.fill: parent Keys.onPressed: { timer.stop() var code = konami.code if (event.key === code[index]) { // 1. Code OK. if (++index === code.length) { index = 0 konami.triggered() return } // 2. Actual key OK. if (delay > 0) { timer.start() } return } // 3. Wrong key. index = 0 } } } linphone-desktop-4.2.5/linphone-app/ui/modules/Konami/qmldir000066400000000000000000000001671376717241300241340ustar00rootroot00000000000000module Konami // ============================================================================= Konami 1.0 Konami.qml linphone-desktop-4.2.5/linphone-app/ui/modules/Linphone/000077500000000000000000000000001376717241300232535ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/ui/modules/Linphone/Account/000077500000000000000000000000001376717241300246475ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/ui/modules/Linphone/Account/AccountStatus.qml000066400000000000000000000057261376717241300301740ustar00rootroot00000000000000import QtQuick 2.7 import QtQuick.Controls 2.2 import QtQuick.Layouts 1.3 import Common 1.0 import Linphone 1.0 import Linphone.Styles 1.0 // ============================================================================= Item { id: accountStatus // --------------------------------------------------------------------------- signal clicked property alias cursorShape:mouseArea.cursorShape // --------------------------------------------------------------------------- RowLayout { anchors.fill: parent Column { Layout.fillWidth: true Layout.fillHeight: true RowLayout { height: parent.height / 2 spacing: AccountStatusStyle.horizontalSpacing width: parent.width Item { Layout.alignment: Qt.AlignBottom Layout.bottomMargin: AccountStatusStyle.presenceLevel.bottomMargin Layout.preferredHeight: AccountStatusStyle.presenceLevel.size Layout.preferredWidth: AccountStatusStyle.presenceLevel.size PresenceLevel { anchors.fill: parent level: OwnPresenceModel.presenceStatus===Presence.Offline?Presence.White:( SettingsModel.rlsUriEnabled ? OwnPresenceModel.presenceLevel : Presence.Green) visible: AccountSettingsModel.registrationState === AccountSettingsModel.RegistrationStateRegistered } BusyIndicator { anchors.fill: parent running: AccountSettingsModel.registrationState === AccountSettingsModel.RegistrationStateInProgress } Icon { iconSize: parent.width icon: 'generic_error' visible: AccountSettingsModel.registrationState === AccountSettingsModel.RegistrationStateNotRegistered || AccountSettingsModel.registrationState === AccountSettingsModel.RegistrationStateNoProxy TooltipArea{ text : 'Not Registered' } } } Text { Layout.fillHeight: true Layout.fillWidth: true color: AccountStatusStyle.username.color elide: Text.ElideRight font.bold: true font.pointSize: AccountStatusStyle.username.pointSize text: AccountSettingsModel.username verticalAlignment: Text.AlignBottom } } Text { color: AccountStatusStyle.sipAddress.color elide: Text.ElideRight font.pointSize: AccountStatusStyle.sipAddress.pointSize height: parent.height / 2 text: AccountSettingsModel.sipAddress verticalAlignment: Text.AlignTop width: parent.width } } Item { Layout.preferredWidth: MessageCounterStyle.iconSize.message Layout.preferredHeight: MessageCounterStyle.iconSize.message MessageCounter { id: messageCounter anchors.fill: parent count: CoreManager.eventCount } } } MouseArea { id:mouseArea anchors.fill: parent onClicked: accountStatus.clicked() } } linphone-desktop-4.2.5/linphone-app/ui/modules/Linphone/Blocks/000077500000000000000000000000001376717241300244705ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/ui/modules/Linphone/Blocks/CardBlock.qml000066400000000000000000000030321376717241300270250ustar00rootroot00000000000000import QtQuick 2.7 import Common 1.0 import Linphone.Styles 1.0 // ============================================================================= Column { default property alias _content: content.data property alias icon: icon.icon property alias title: title.text property alias description: description.text // --------------------------------------------------------------------------- spacing: CardBlockStyle.spacing width: CardBlockStyle.width Icon { id: icon iconSize: CardBlockStyle.icon.size height: CardBlockStyle.icon.size + CardBlockStyle.icon.bottomMargin width: parent.width } Column { spacing: CardBlockStyle.title.bottomMargin width: parent.width Text { id: title color: CardBlockStyle.title.color elide: Text.ElideRight horizontalAlignment: Text.AlignHCenter wrapMode: Text.WordWrap font { bold: true pointSize: CardBlockStyle.title.pointSize } height: CardBlockStyle.title.height width: parent.width } Text { id: description color: CardBlockStyle.description.color elide: Text.ElideRight font.pointSize: CardBlockStyle.description.pointSize horizontalAlignment: Text.AlignHCenter wrapMode: Text.WordWrap height: CardBlockStyle.description.height width: parent.width } } // --------------------------------------------------------------------------- Item { id: content height: CardBlockStyle.content.height width: parent.width } } linphone-desktop-4.2.5/linphone-app/ui/modules/Linphone/Blocks/RequestBlock.qml000066400000000000000000000025001376717241300276030ustar00rootroot00000000000000import QtQuick 2.7 import Common 1.0 import Linphone.Styles 1.0 // ============================================================================= Item { id: block property var action readonly property alias loading: block._loading property bool _loading: false // ---------------------------------------------------------------------------- function execute () { block._loading = true action() } function setText(txt){ errorBlock.text = txt } function stop (error) { errorBlock.text = error block._loading = false } // ---------------------------------------------------------------------------- height: RequestBlockStyle.height TextEdit { id: errorBlock readOnly: true selectByMouse: true color: RequestBlockStyle.error.color font { italic: true pointSize: RequestBlockStyle.error.pointSize } height: parent.height width: parent.width horizontalAlignment: Text.AlignHCenter padding: RequestBlockStyle.error.padding wrapMode: Text.WordWrap visible: !block.loading } BusyIndicator { anchors { horizontalCenter: parent.horizontalCenter top: parent.top } height: RequestBlockStyle.loadingIndicator.height width: RequestBlockStyle.loadingIndicator.width running: block.loading } } linphone-desktop-4.2.5/linphone-app/ui/modules/Linphone/Calls/000077500000000000000000000000001376717241300243115ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/ui/modules/Linphone/Calls/CallControls.qml000066400000000000000000000032501376717241300274230ustar00rootroot00000000000000import QtQuick 2.7 import QtQuick.Layouts 1.3 import Common 1.0 import Linphone 1.0 import Linphone.Styles 1.0 // ============================================================================= Rectangle { id: callControls // --------------------------------------------------------------------------- default property alias _content: content.data property alias signIcon: signIcon.icon property alias sipAddressColor: contact.sipAddressColor property alias usernameColor: contact.usernameColor property string peerAddress property string localAddress property string fullPeerAddress property string fullLocalAddress // --------------------------------------------------------------------------- signal clicked // --------------------------------------------------------------------------- color: CallControlsStyle.color height: CallControlsStyle.height MouseArea { anchors.fill: parent onClicked: callControls.clicked() } Icon { id: signIcon anchors { left: parent.left top: parent.top } iconSize: CallControlsStyle.signSize } RowLayout { anchors { fill: parent leftMargin: CallControlsStyle.leftMargin rightMargin: CallControlsStyle.rightMargin } spacing: 0 Contact { id: contact Layout.fillHeight: true Layout.fillWidth: true displayUnreadMessageCount: true entry: SipAddressesModel.getSipAddressObserver((fullPeerAddress?fullPeerAddress:peerAddress), (fullLocalAddress?fullLocalAddress:localAddress)) } Item { id: content Layout.fillHeight: true Layout.preferredWidth: callControls._content[0].width } } } linphone-desktop-4.2.5/linphone-app/ui/modules/Linphone/Calls/CallStatistics.qml000066400000000000000000000053561376717241300277630ustar00rootroot00000000000000import QtQuick 2.7 import QtQuick.Layouts 1.3 import Common 1.0 import Linphone 1.0 import Linphone.Styles 1.0 // ============================================================================= Popup { id: callStatistics property var call // --------------------------------------------------------------------------- Rectangle { color: CallStatisticsStyle.color height: CallStatisticsStyle.height width: callStatistics.width Row { anchors { fill: parent topMargin: CallStatisticsStyle.topMargin leftMargin: CallStatisticsStyle.leftMargin rightMargin: CallStatisticsStyle.rightMargin } Loader { property string $label: qsTr('audioStatsLabel') property var $data: callStatistics.call?callStatistics.call.audioStats:null sourceComponent: media width: parent.width / 2 } Loader { property string $label: qsTr('videoStatsLabel') property var $data: callStatistics.call?callStatistics.call.videoStats:null sourceComponent: media width: parent.width / 2 } } // ------------------------------------------------------------------------- // Line. // ------------------------------------------------------------------------- Component { id: line RowLayout { spacing: CallStatisticsStyle.spacing width: parent.width Text { Layout.preferredWidth: CallStatisticsStyle.key.width color: CallStatisticsStyle.key.color elide: Text.ElideRight font { pointSize: CallStatisticsStyle.key.pointSize bold: true } horizontalAlignment: Text.AlignRight verticalAlignment: Text.AlignVCenter text: modelData.key } Text { Layout.fillWidth: true color: CallStatisticsStyle.value.color elide: Text.ElideRight font.pointSize: CallStatisticsStyle.value.pointSize text: modelData.value } } } // ------------------------------------------------------------------------- // Media. // ------------------------------------------------------------------------- Component { id: media Column { Text { color: CallStatisticsStyle.title.color font { bold: true pointSize: CallStatisticsStyle.title.pointSize } elide: Text.ElideRight horizontalAlignment: Text.AlignHCenter text: $label height: contentHeight + CallStatisticsStyle.title.bottomMargin width: parent.width } Repeater { model: $data delegate: line } } } } } linphone-desktop-4.2.5/linphone-app/ui/modules/Linphone/Calls/Calls.js000066400000000000000000000125201376717241300257050ustar00rootroot00000000000000/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ // ============================================================================= // `Calls.qml` Logic. // ============================================================================= .import Linphone 1.0 as Linphone // ============================================================================= // ----------------------------------------------------------------------------- // Helpers. // ----------------------------------------------------------------------------- function getParams (call) { if (!call) { return } var CallModel = Linphone.CallModel var status = call.status if (status === CallModel.CallStatusConnected) { var optActions = [] if (Linphone.SettingsModel.callPauseEnabled) { optActions.push({ handler: (function () { call.pausedByUser = true }), name: qsTr('callPause') }) } return { actions: optActions.concat([{ handler: call.askForTransfer, name: qsTr('transferCall') }, { handler: call.terminate, name: qsTr('terminateCall') }]), component: callActions, string: 'connected' } } if (status === CallModel.CallStatusEnded) { return { string: 'ended' } } if (status === CallModel.CallStatusIncoming) { var optActions = [] if (Linphone.SettingsModel.videoSupported) { optActions.push({ handler: call.acceptWithVideo, name: qsTr('acceptVideoCall') }) } return { actions: [{ handler: (function () { call.accept() }), name: qsTr('acceptAudioCall') }].concat(optActions).concat([{ handler: call.terminate, name: qsTr('terminateCall') }]), component: callActions, string: 'incoming' } } if (status === CallModel.CallStatusOutgoing) { return { component: callAction, handler: call.terminate, icon: 'hangup', string: 'outgoing' } } if (status === CallModel.CallStatusPaused) { var optActions = [] if (call.pausedByUser) { optActions.push({ handler: (function () { call.pausedByUser = false }), name: qsTr('resumeCall') }) } else if (Linphone.SettingsModel.callPauseEnabled) { optActions.push({ handler: (function () { call.pausedByUser = true }), name: qsTr('callPause') }) } return { actions: optActions.concat([{ handler: call.askForTransfer, name: qsTr('transferCall') }, { handler: call.terminate, name: qsTr('terminateCall') }]), component: callActions, string: 'paused' } } } function updateSelectedCall (call, index) { calls._selectedCall = call if (index != null) { calls.currentIndex = index } } function resetSelectedCall () { updateSelectedCall(null, -1) } function setIndexWithCall (call) { var count = calls.count var model = calls.model for (var i = 0; i < count; i++) { if (call === model.data(model.index(i, 0))) { updateSelectedCall(call, i) return } } updateSelectedCall(call, -1) } // ----------------------------------------------------------------------------- // View handlers. // ----------------------------------------------------------------------------- function handleCountChanged (count) { if (count === 0) { return } var call = calls._selectedCall if (call == null) { if (calls.conferenceModel.count > 0) { return } var model = calls.model var index = count - 1 updateSelectedCall(model.data(model.index(index, 0)), index) } else { setIndexWithCall(call) } } // ----------------------------------------------------------------------------- // Model handlers. // ----------------------------------------------------------------------------- function handleCallRunning (call) { if (!call.isInConference) { setIndexWithCall(call) } } function handleRowsAboutToBeRemoved (_, first, last) { var index = calls.currentIndex if (index >= first && index <= last) { resetSelectedCall() } } function handleRowsInserted (_, first, last) { // The last inserted outgoing element become the selected call. var model = calls.model for (var index = last; index >= first; index--) { var call = model.data(model.index(index, 0)) if (call.isOutgoing && !call.isInConference) { updateSelectedCall(call) return } } // First received call. if (first === 0 && model.rowCount() === 1) { var call = model.data(model.index(0, 0)) if (!call.isInConference) { updateSelectedCall(model.data(model.index(0, 0))) } } } linphone-desktop-4.2.5/linphone-app/ui/modules/Linphone/Calls/Calls.qml000066400000000000000000000117301376717241300260640ustar00rootroot00000000000000import QtQuick 2.7 import Common 1.0 import Linphone 1.0 import Linphone.Styles 1.0 import 'Calls.js' as Logic // ============================================================================= ListView { id: calls // --------------------------------------------------------------------------- readonly property var selectedCall: calls._selectedCall property var conferenceModel property var _selectedCall // --------------------------------------------------------------------------- boundsBehavior: Flickable.StopAtBounds clip: true spacing: 0 // --------------------------------------------------------------------------- onCountChanged: Logic.handleCountChanged(count) Connections { target: model onCallRunning: Logic.handleCallRunning(callModel) onRowsAboutToBeRemoved: Logic.handleRowsAboutToBeRemoved(parent, first, last) onRowsInserted: Logic.handleRowsInserted(parent, first, last) } // --------------------------------------------------------------------------- Component { id: callAction ActionButton { icon: params.icon || 'generic_error' iconSize: CallsStyle.entry.iconActionSize onClicked: params.handler() } } Component { id: callActions ActionButton { id: button icon: calls.currentIndex === callId && call.status !== CallModel.CallStatusEnded ? 'burger_menu_light' : 'burger_menu' iconSize: CallsStyle.entry.iconMenuSize onClicked: menu.open() DropDownStaticMenu { id: menu relativeTo: callControls relativeX: callControls.width entryHeight: CallsStyle.entry.height entryWidth: CallsStyle.entry.width Repeater { model: params ? params.actions : [] DropDownStaticMenuEntry { entryName: modelData.name onClicked: { menu.close() params.actions[index].handler() } } } } } } // --------------------------------------------------------------------------- // Conference. // --------------------------------------------------------------------------- header: ConferenceControls { readonly property bool isSelected: calls.currentIndex === -1 && calls._selectedCall == null height: visible ? ConferenceControlsStyle.height : 0 width: parent.width visible: calls.conferenceModel.count > 0 color: isSelected ? CallsStyle.entry.color.selected : CallsStyle.entry.color.normal textColor: isSelected ? CallsStyle.entry.usernameColor.selected : CallsStyle.entry.usernameColor.normal onClicked: Logic.resetSelectedCall() onVisibleChanged: !visible && Logic.handleCountChanged(calls.count) } // --------------------------------------------------------------------------- // Calls. // --------------------------------------------------------------------------- delegate: CallControls { id: _callControls // ------------------------------------------------------------------------- function useColorStatus () { return calls.currentIndex === index && $call && $call.status !== CallModel.CallStatusEnded } // ------------------------------------------------------------------------- color: useColorStatus() ? CallsStyle.entry.color.selected : CallsStyle.entry.color.normal sipAddressColor: useColorStatus() ? CallsStyle.entry.sipAddressColor.selected : CallsStyle.entry.sipAddressColor.normal usernameColor: useColorStatus() ? CallsStyle.entry.usernameColor.selected : CallsStyle.entry.usernameColor.normal signIcon: { var params = loader.params return params ? 'call_sign_' + params.string : '' } peerAddress: $call.peerAddress localAddress: $call.localAddress fullPeerAddress: $call.fullPeerAddress fullLocalAddress: $call.fullLocalAddress width: parent.width onClicked: { if ($call.status !== CallModel.CallStatusEnded) { Logic.updateSelectedCall($call, index) } } // ------------------------------------------------------------------------- Loader { id: loader readonly property int callId: index readonly property var call: $call readonly property var callControls: _callControls readonly property var params: Logic.getParams($call) anchors.centerIn: parent sourceComponent: params ? params.component : null } SequentialAnimation on color { loops: CallsStyle.entry.endCallAnimation.loops running: !$call || $call.status === CallModel.CallStatusEnded ColorAnimation { duration: CallsStyle.entry.endCallAnimation.duration from: CallsStyle.entry.color.normal to: CallsStyle.entry.endCallAnimation.blinkColor } ColorAnimation { duration: CallsStyle.entry.endCallAnimation.duration from: CallsStyle.entry.endCallAnimation.blinkColor to: CallsStyle.entry.color.normal } } } } linphone-desktop-4.2.5/linphone-app/ui/modules/Linphone/Calls/ConferenceControls.qml000066400000000000000000000020551376717241300306210ustar00rootroot00000000000000import QtQuick 2.7 import QtQuick.Layouts 1.3 import Common 1.0 import Linphone 1.0 import Linphone.Styles 1.0 // ============================================================================= Rectangle { id: callControls // --------------------------------------------------------------------------- property alias textColor: text.color // --------------------------------------------------------------------------- signal clicked // --------------------------------------------------------------------------- color: ConferenceControlsStyle.color height: ConferenceControlsStyle.height MouseArea { anchors.fill: parent onClicked: callControls.clicked() } RowLayout { anchors { fill: parent leftMargin: ConferenceControlsStyle.leftMargin rightMargin: ConferenceControlsStyle.rightMargin } spacing: 0 Text { id: text Layout.fillHeight: true Layout.fillWidth: true font.bold: true text: qsTr('conference') verticalAlignment: Text.AlignVCenter } } } linphone-desktop-4.2.5/linphone-app/ui/modules/Linphone/Chat/000077500000000000000000000000001376717241300241325ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/ui/modules/Linphone/Chat/Chat.js000066400000000000000000000051701376717241300253520ustar00rootroot00000000000000/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ // ============================================================================= // `Chat.qml` Logic. // ============================================================================= .import QtQuick 2.7 as QtQuick .import Linphone 1.0 as Linphone .import 'qrc:/ui/scripts/LinphoneUtils/linphone-utils.js' as LinphoneUtils // ============================================================================= function initView () { chat.tryToLoadMoreEntries = false chat.bindToEnd = true } function loadMoreEntries () { if (chat.atYBeginning && !chat.tryToLoadMoreEntries) { chat.tryToLoadMoreEntries = true chat.positionViewAtBeginning() container.proxyModel.loadMoreEntries() } } function getComponentFromEntry (chatEntry) { if (chatEntry.fileName) { return 'FileMessage.qml' } if (chatEntry.type === Linphone.ChatModel.CallEntry) { return 'Event.qml' } return chatEntry.isOutgoing ? 'OutgoingMessage.qml' : 'IncomingMessage.qml' } function getIsComposingMessage () { if (!container.proxyModel.isRemoteComposing || !Linphone.SettingsModel.chatEnabled) { return '' } var sipAddressObserver = chat.sipAddressObserver return qsTr('isComposing').replace( '%1', LinphoneUtils.getContactUsername(sipAddressObserver) ) } function handleFilesDropped (files) { chat.bindToEnd = true files.forEach(container.proxyModel.sendFileMessage) } function handleMoreEntriesLoaded (n) { chat.positionViewAtIndex(n - 1, QtQuick.ListView.Beginning) chat.tryToLoadMoreEntries = false } function handleMovementEnded () { if (chat.atYEnd) { chat.bindToEnd = true } } function handleMovementStarted () { chat.bindToEnd = false } function handleTextChanged (text) { container.proxyModel.compose(text) } function sendMessage (text) { textArea.text = '' chat.bindToEnd = true container.proxyModel.sendMessage(text) } linphone-desktop-4.2.5/linphone-app/ui/modules/Linphone/Chat/Chat.qml000066400000000000000000000161241376717241300255300ustar00rootroot00000000000000import QtQuick 2.7 import QtQuick.Controls 2.2 import QtQuick.Layouts 1.3 import Common 1.0 import Linphone 1.0 import Linphone.Styles 1.0 import 'Chat.js' as Logic // ============================================================================= Rectangle { id: container property alias proxyModel: chat.model // --------------------------------------------------------------------------- signal messageToSend (string text) // --------------------------------------------------------------------------- color: ChatStyle.color ColumnLayout { anchors.fill: parent spacing: 0 ScrollableListView { id: chat // ----------------------------------------------------------------------- property bool bindToEnd: false property bool tryToLoadMoreEntries: true property var sipAddressObserver: SipAddressesModel.getSipAddressObserver(proxyModel.fullPeerAddress, proxyModel.fullLocalAddress) // ----------------------------------------------------------------------- Layout.fillHeight: true Layout.fillWidth: true highlightFollowsCurrentItem: false section { criteria: ViewSection.FullString delegate: sectionHeading property: '$sectionDate' } // ----------------------------------------------------------------------- Component.onCompleted: Logic.initView() onContentYChanged: Logic.loadMoreEntries() onMovementEnded: Logic.handleMovementEnded() onMovementStarted: Logic.handleMovementStarted() // ----------------------------------------------------------------------- Connections { target: proxyModel // When the view is changed (for example `Calls` -> `Messages`), // the position is set at end and it can be possible to load // more entries. onEntryTypeFilterChanged: Logic.initView() onMoreEntriesLoaded: Logic.handleMoreEntriesLoaded(n) } // ----------------------------------------------------------------------- // Heading. // ----------------------------------------------------------------------- Component { id: sectionHeading Item { implicitHeight: container.height + ChatStyle.sectionHeading.bottomMargin width: parent.width Borders { id: container borderColor: ChatStyle.sectionHeading.border.color bottomWidth: ChatStyle.sectionHeading.border.width implicitHeight: text.contentHeight + ChatStyle.sectionHeading.padding * 2 + ChatStyle.sectionHeading.border.width * 2 topWidth: ChatStyle.sectionHeading.border.width width: parent.width Text { id: text anchors.fill: parent color: ChatStyle.sectionHeading.text.color font { bold: true pointSize: ChatStyle.sectionHeading.text.pointSize } horizontalAlignment: Text.AlignHCenter verticalAlignment: Text.AlignVCenter // Cast section to integer because Qt converts the // sectionDate in string!!! text: new Date(section).toLocaleDateString( Qt.locale(App.locale) ) } } } } // ----------------------------------------------------------------------- // Message/Event renderer. // ----------------------------------------------------------------------- delegate: Rectangle { id: entry function isHoverEntry () { return mouseArea.containsMouse } function removeEntry () { proxyModel.removeEntry(index) } anchors { left: parent ? parent.left : undefined leftMargin: ChatStyle.entry.leftMargin right: parent ? parent.right : undefined rightMargin: ChatStyle.entry.deleteIconSize + ChatStyle.entry.message.extraContent.spacing + ChatStyle.entry.message.extraContent.rightMargin + ChatStyle.entry.message.extraContent.leftMargin + ChatStyle.entry.message.outgoing.areaSize } color: ChatStyle.color implicitHeight: layout.height + ChatStyle.entry.bottomMargin // --------------------------------------------------------------------- MouseArea { id: mouseArea cursorShape: Qt.ArrowCursor hoverEnabled: true implicitHeight: layout.height width: parent.width + parent.anchors.rightMargin RowLayout { id: layout spacing: 0 width: entry.width // Display time. Text { Layout.alignment: Qt.AlignTop Layout.preferredHeight: ChatStyle.entry.lineHeight Layout.preferredWidth: ChatStyle.entry.time.width color: ChatStyle.entry.time.color font.pointSize: ChatStyle.entry.time.pointSize text: $chatEntry.timestamp.toLocaleString( Qt.locale(App.locale), 'hh:mm' ) verticalAlignment: Text.AlignVCenter TooltipArea { text: $chatEntry.timestamp.toLocaleString(Qt.locale(App.locale)) } } // Display content. Loader { Layout.fillWidth: true source: Logic.getComponentFromEntry($chatEntry) } } } } footer: Text { color: ChatStyle.composingText.color font.pointSize: ChatStyle.composingText.pointSize height: visible ? ChatStyle.composingText.height : 0 leftPadding: ChatStyle.composingText.leftPadding visible: text.length > 0 text: Logic.getIsComposingMessage() } } // ------------------------------------------------------------------------- // Send area. // ------------------------------------------------------------------------- Borders { Layout.fillWidth: true Layout.preferredHeight: ChatStyle.sendArea.height + ChatStyle.sendArea.border.width borderColor: ChatStyle.sendArea.border.color topWidth: ChatStyle.sendArea.border.width visible: SettingsModel.chatEnabled DroppableTextArea { id: textArea anchors.fill: parent dropEnabled: SettingsModel.fileTransferUrl.length > 0 dropDisabledReason: qsTr('noFileTransferUrl') placeholderText: qsTr('newMessagePlaceholder') onDropped: Logic.handleFilesDropped(files) onTextChanged: Logic.handleTextChanged(text) onValidText: Logic.sendMessage(text) Component.onCompleted: {text = proxyModel.cachedText; cursorPosition=text.length} } } } // --------------------------------------------------------------------------- // Scroll at end if necessary. // --------------------------------------------------------------------------- Timer { interval: 100 repeat: true running: true onTriggered: chat.bindToEnd && chat.positionViewAtEnd() } } linphone-desktop-4.2.5/linphone-app/ui/modules/Linphone/Chat/Event.qml000066400000000000000000000046141376717241300257330ustar00rootroot00000000000000import QtQuick 2.7 import Common 1.0 import Linphone 1.0 import Linphone.Styles 1.0 import Utils 1.0 // ============================================================================= Row { property string _type: { var status = $chatEntry.status if (status === ChatModel.CallStatusSuccess) { if (!$chatEntry.isStart) { return 'ended_call' } return $chatEntry.isOutgoing ? 'outgoing_call' : 'incoming_call' } if (status === ChatModel.CallStatusDeclined) { return $chatEntry.isOutgoing ? 'declined_outgoing_call' : 'declined_incoming_call' } if (status === ChatModel.CallStatusMissed) { return $chatEntry.isOutgoing ? 'missed_outgoing_call' : 'missed_incoming_call' } if (status === ChatModel.CallStatusAborted) { return $chatEntry.isOutgoing ? 'outgoing_call' : 'incoming_call' } if (status === ChatModel.CallStatusEarlyAborted) { return $chatEntry.isOutgoing ? 'missed_outgoing_call' : 'missed_incoming_call' } if (status === ChatModel.CallStatusAcceptedElsewhere) { return $chatEntry.isOutgoing ? 'outgoing_call' : 'incoming_call' } if (status === ChatModel.CallStatusDeclinedElsewhere) { return $chatEntry.isOutgoing ? 'declined_outgoing_call' : 'declined_incoming_call' } return 'unknown_call_event' } height: ChatStyle.entry.lineHeight spacing: ChatStyle.entry.message.extraContent.spacing Icon { height: parent.height icon: _type iconSize: ChatStyle.entry.event.iconSize width: ChatStyle.entry.metaWidth } Text { Component { // Never created. // Private data for `lupdate`. Item { property var i18n: [ QT_TR_NOOP('declinedIncomingCall'), QT_TR_NOOP('declinedOutgoingCall'), QT_TR_NOOP('endedCall'), QT_TR_NOOP('incomingCall'), QT_TR_NOOP('missedIncomingCall'), QT_TR_NOOP('missedOutgoingCall'), QT_TR_NOOP('outgoingCall') ] } } color: ChatStyle.entry.event.text.color font { bold: true pointSize: ChatStyle.entry.event.text.pointSize } height: parent.height text: qsTr(Utils.snakeToCamel(_type)) verticalAlignment: Text.AlignVCenter } ActionButton { height: ChatStyle.entry.lineHeight icon: 'delete' iconSize: ChatStyle.entry.deleteIconSize visible: isHoverEntry() onClicked: removeEntry() } } linphone-desktop-4.2.5/linphone-app/ui/modules/Linphone/Chat/FileMessage.qml000066400000000000000000000234721376717241300270410ustar00rootroot00000000000000import QtQuick 2.7 import QtQuick.Controls 2.2 import QtQuick.Layouts 1.3 import Common 1.0 import Linphone 1.0 import LinphoneUtils 1.0 import Linphone.Styles 1.0 import Utils 1.0 // ============================================================================= Row { // --------------------------------------------------------------------------- // Avatar if it's an incoming message. // --------------------------------------------------------------------------- Item { height: ChatStyle.entry.lineHeight width: ChatStyle.entry.metaWidth Component { id: avatar Avatar { height: ChatStyle.entry.message.incoming.avatarSize width: ChatStyle.entry.message.incoming.avatarSize image: chat.sipAddressObserver.contact ? chat.sipAddressObserver.contact.vcard.avatar : '' username: LinphoneUtils.getContactUsername(chat.sipAddressObserver) } } Loader { anchors.centerIn: parent sourceComponent: !$chatEntry.isOutgoing ? avatar : undefined } } // --------------------------------------------------------------------------- // File message. // --------------------------------------------------------------------------- Row { spacing: ChatStyle.entry.message.extraContent.leftMargin Rectangle { id: rectangle readonly property bool isError: Utils.includes([ ChatModel.MessageStatusFileTransferError, ChatModel.MessageStatusNotDelivered, ], $chatEntry.status) readonly property bool isUploaded: $chatEntry.status === ChatModel.MessageStatusDelivered readonly property bool isDelivered: $chatEntry.status === ChatModel.MessageStatusDeliveredToUser readonly property bool isRead: $chatEntry.status === ChatModel.MessageStatusDisplayed color: $chatEntry.isOutgoing ? ChatStyle.entry.message.outgoing.backgroundColor : ChatStyle.entry.message.incoming.backgroundColor height: ChatStyle.entry.message.file.height width: ChatStyle.entry.message.file.width radius: ChatStyle.entry.message.radius RowLayout { anchors { fill: parent margins: ChatStyle.entry.message.file.margins } spacing: ChatStyle.entry.message.file.spacing // --------------------------------------------------------------------- // Thumbnail or extension. // --------------------------------------------------------------------- Component { id: thumbnail Image { mipmap: Qt.platform.os === 'osx' source: $chatEntry.thumbnail } } Component { id: extension Rectangle { color: ChatStyle.entry.message.file.extension.background.color Text { anchors.fill: parent color: ChatStyle.entry.message.file.extension.text.color font.bold: true elide: Text.ElideRight text: Utils.getExtension($chatEntry.fileName).toUpperCase() horizontalAlignment: Text.AlignHCenter verticalAlignment: Text.AlignVCenter } } } Loader { id: thumbnailProvider Layout.fillHeight: true Layout.preferredWidth: parent.height sourceComponent: $chatEntry.thumbnail ? thumbnail : extension ScaleAnimator { id: thumbnailProviderAnimator target: thumbnailProvider duration: ChatStyle.entry.message.file.animation.duration easing.type: Easing.InOutQuad from: 1.0 } states: State { name: 'hovered' } transitions: [ Transition { from: '' to: 'hovered' ScriptAction { script: { if (thumbnailProviderAnimator.running) { thumbnailProviderAnimator.running = false } thumbnailProvider.z = Constants.zPopup thumbnailProviderAnimator.to = ChatStyle.entry.message.file.animation.to thumbnailProviderAnimator.running = true } } }, Transition { from: 'hovered' to: '' ScriptAction { script: { if (thumbnailProviderAnimator.running) { thumbnailProviderAnimator.running = false } thumbnailProviderAnimator.to = 1.0 thumbnailProviderAnimator.running = true thumbnailProvider.z = 0 } } } ] } // --------------------------------------------------------------------- // Upload or file status. // --------------------------------------------------------------------- Column { Layout.fillWidth: true Layout.fillHeight: true spacing: ChatStyle.entry.message.file.status.spacing Text { id: fileName color: $chatEntry.isOutgoing ? ChatStyle.entry.message.outgoing.text.color : ChatStyle.entry.message.incoming.text.color elide: Text.ElideRight font { bold: true pointSize: $chatEntry.isOutgoing ? ChatStyle.entry.message.outgoing.text.pointSize : ChatStyle.entry.message.incoming.text.pointSize } text: $chatEntry.fileName width: parent.width } ProgressBar { id: progressBar height: ChatStyle.entry.message.file.status.bar.height width: parent.width to: $chatEntry.fileSize value: $chatEntry.fileOffset || 0 visible: $chatEntry.status === ChatModel.MessageStatusInProgress || $chatEntry.status === ChatModel.MessageStatusFileTransferInProgress background: Rectangle { color: ChatStyle.entry.message.file.status.bar.background.color radius: ChatStyle.entry.message.file.status.bar.radius } contentItem: Item { Rectangle { color: ChatStyle.entry.message.file.status.bar.contentItem.color height: parent.height width: progressBar.visualPosition * parent.width radius: ChatStyle.entry.message.file.status.bar.radius } } } Text { color: fileName.color elide: Text.ElideRight font.pointSize: fileName.font.pointSize text: { var fileSize = Utils.formatSize($chatEntry.fileSize) return progressBar.visible ? Utils.formatSize($chatEntry.fileOffset) + '/' + fileSize : fileSize } } } } Icon { anchors { bottom: parent.bottom bottomMargin: ChatStyle.entry.message.file.margins right: parent.right rightMargin: ChatStyle.entry.message.file.margins } icon: 'download' iconSize: ChatStyle.entry.message.file.iconSize visible: !$chatEntry.isOutgoing && !$chatEntry.wasDownloaded } MouseArea { function handleMouseMove (mouse) { thumbnailProvider.state = Utils.pointIsInItem(this, thumbnailProvider, mouse) ? 'hovered' : '' } anchors.fill: parent visible: (rectangle.isUploaded || rectangle.isRead) && !$chatEntry.isOutgoing onClicked: { if (Utils.pointIsInItem(this, thumbnailProvider, mouse)) { proxyModel.openFile(index) } else if ($chatEntry.wasDownloaded) { proxyModel.openFileDirectory(index) } else { proxyModel.downloadFile(index) } } onExited: thumbnailProvider.state = '' onMouseXChanged: handleMouseMove.call(this, mouse) onMouseYChanged: handleMouseMove.call(this, mouse) } } // ------------------------------------------------------------------------- // Resend/Remove file message. // ------------------------------------------------------------------------- Row { spacing: ChatStyle.entry.message.extraContent.spacing Component { id: icon Icon { anchors.centerIn: parent icon: rectangle.isError ? 'chat_error' : (rectangle.isRead ? 'chat_read' : (rectangle.isDelivered ? 'chat_delivered' : '')) iconSize: ChatStyle.entry.message.outgoing.sendIconSize MouseArea { anchors.fill: parent visible: (rectangle.isError || $chatEntry.status === ChatModel.MessageStatusIdle) && $chatEntry.isOutgoing onClicked: proxyModel.resendMessage(index) } } } Component { id: indicator Item { anchors.fill: parent BusyIndicator { anchors.centerIn: parent height: ChatStyle.entry.message.outgoing.busyIndicatorSize width: ChatStyle.entry.message.outgoing.busyIndicatorSize } } } Loader { height: ChatStyle.entry.lineHeight width: ChatStyle.entry.message.outgoing.areaSize sourceComponent: $chatEntry.isOutgoing ? ( $chatEntry.status === ChatModel.MessageStatusInProgress || $chatEntry.status === ChatModel.MessageStatusFileTransferInProgress ? indicator : icon ) : undefined } ActionButton { height: ChatStyle.entry.lineHeight icon: 'delete' iconSize: ChatStyle.entry.deleteIconSize visible: isHoverEntry() onClicked: removeEntry() } } } } linphone-desktop-4.2.5/linphone-app/ui/modules/Linphone/Chat/IncomingMessage.qml000066400000000000000000000040001376717241300277070ustar00rootroot00000000000000import QtQuick 2.7 import QtQuick.Layouts 1.3 import Common 1.0 import Linphone 1.0 import Linphone.Styles 1.0 import LinphoneUtils 1.0 // ============================================================================= RowLayout { implicitHeight: message.height spacing: 0 Item { Layout.alignment: Qt.AlignTop Layout.preferredHeight: ChatStyle.entry.lineHeight Layout.preferredWidth: ChatStyle.entry.metaWidth Avatar { anchors.centerIn: parent height: ChatStyle.entry.message.incoming.avatarSize image: chat.sipAddressObserver.contact ? chat.sipAddressObserver.contact.vcard.avatar : '' username: LinphoneUtils.getContactUsername(chat.sipAddressObserver) width: ChatStyle.entry.message.incoming.avatarSize // The avatar is only visible for the first message of a incoming messages sequence. visible: { if (index <= 0) { return true // 1. First message, so visible. } var previousEntry = proxyModel.data(proxyModel.index(index - 1, 0)) if (!previousEntry) { return true } // 2. Previous entry is a call event. => Visible. // 3. I have sent a message before my contact. => Visible. // 4. One hour between two incoming messages. => Visible. return previousEntry.type !== ChatModel.MessageEntry || previousEntry.isOutgoing || $chatEntry.timestamp.getTime() - previousEntry.timestamp.getTime() > 3600 } } } Message { id: message Layout.fillWidth: true // Not a style. Workaround to avoid a 0 width. // Arbitrary value. Layout.minimumWidth: 1 backgroundColor: ChatStyle.entry.message.incoming.backgroundColor color: ChatStyle.entry.message.incoming.text.color pointSize: ChatStyle.entry.message.incoming.text.pointSize ActionButton { height: ChatStyle.entry.lineHeight icon: 'delete' iconSize: ChatStyle.entry.deleteIconSize visible: isHoverEntry() onClicked: removeEntry() } } } linphone-desktop-4.2.5/linphone-app/ui/modules/Linphone/Chat/Message.js000066400000000000000000000031111376717241300260500ustar00rootroot00000000000000/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ // ============================================================================= // `Message.qml` Logic. // ============================================================================= // See: `ensureVisible` on http://doc.qt.io/qt-5/qml-qtquick-textedit.html function ensureVisible (cursor) { // Case 1: No focused. if (!message.activeFocus) { return } // Case 2: Scroll up. var contentItem = chat.contentItem var contentY = chat.contentY var messageY = message.mapToItem(contentItem, 0, 0).y + cursor.y if (contentY >= messageY) { chat.contentY = messageY return } // Case 3: Scroll down. var chatHeight = chat.height var cursorHeight = cursor.height if (contentY + chatHeight <= messageY + cursorHeight) { chat.contentY = messageY + cursorHeight - chatHeight } } linphone-desktop-4.2.5/linphone-app/ui/modules/Linphone/Chat/Message.qml000066400000000000000000000054171376717241300262400ustar00rootroot00000000000000import QtQuick 2.7 import Clipboard 1.0 import Common 1.0 import Linphone.Styles 1.0 import TextToSpeech 1.0 import Utils 1.0 import 'Message.js' as Logic // ============================================================================= Item { id: container // --------------------------------------------------------------------------- property alias backgroundColor: rectangle.color property alias color: message.color property alias pointSize: message.font.pointSize default property alias _content: content.data // --------------------------------------------------------------------------- implicitHeight: message.contentHeight + message.padding * 2 Rectangle { id: rectangle height: parent.height radius: ChatStyle.entry.message.radius width: ( message.contentWidth < parent.width ? message.contentWidth : parent.width ) + message.padding * 2 } // --------------------------------------------------------------------------- // Message. // --------------------------------------------------------------------------- TextEdit { id: message anchors { left: container.left right: container.right } clip: true padding: ChatStyle.entry.message.padding readOnly: true selectByMouse: true text: Utils.encodeTextToQmlRichFormat($chatEntry.content, { imagesHeight: ChatStyle.entry.message.images.height, imagesWidth: ChatStyle.entry.message.images.width }) // See http://doc.qt.io/qt-5/qml-qtquick-text.html#textFormat-prop // and http://doc.qt.io/qt-5/richtext-html-subset.html textFormat: Text.RichText // To supports links and imgs. wrapMode: TextEdit.Wrap onCursorRectangleChanged: Logic.ensureVisible(cursorRectangle) onLinkActivated: Qt.openUrlExternally(link) onActiveFocusChanged: deselect() Menu { id: messageMenu MenuItem { text: qsTr('menuCopy') onTriggered: Clipboard.text = $chatEntry.content } MenuItem { enabled: TextToSpeech.available text: qsTr('menuPlayMe') onTriggered: TextToSpeech.say($chatEntry.content) } } // Handle hovered link. MouseArea { height: parent.height width: rectangle.width acceptedButtons: Qt.RightButton cursorShape: parent.hoveredLink ? Qt.PointingHandCursor : Qt.IBeamCursor onClicked: mouse.button === Qt.RightButton && messageMenu.open() } } // --------------------------------------------------------------------------- // Extra content. // --------------------------------------------------------------------------- Item { id: content anchors { left: rectangle.right leftMargin: ChatStyle.entry.message.extraContent.leftMargin } } } linphone-desktop-4.2.5/linphone-app/ui/modules/Linphone/Chat/OutgoingMessage.qml000066400000000000000000000055711376717241300277550ustar00rootroot00000000000000import QtQuick 2.7 import QtQuick.Controls 2.2 import QtQuick.Layouts 1.3 import Common 1.0 import Linphone 1.0 import Linphone.Styles 1.0 import Utils 1.0 // ============================================================================= Item { implicitHeight: message.height width: parent.width Message { id: message anchors { left: parent.left leftMargin: ChatStyle.entry.metaWidth right: parent.right } backgroundColor: ChatStyle.entry.message.outgoing.backgroundColor color: ChatStyle.entry.message.outgoing.text.color pointSize: ChatStyle.entry.message.outgoing.text.pointSize width: parent.width Row { spacing: ChatStyle.entry.message.extraContent.spacing Component { id: iconComponent Icon { id: iconId readonly property var isError: Utils.includes([ ChatModel.MessageStatusFileTransferError, ChatModel.MessageStatusNotDelivered, ], $chatEntry.status) readonly property bool isUploaded: $chatEntry.status === ChatModel.MessageStatusDelivered readonly property bool isDelivered: $chatEntry.status === ChatModel.MessageStatusDeliveredToUser readonly property bool isRead: $chatEntry.status === ChatModel.MessageStatusDisplayed icon: isError ? 'chat_error' : (isRead ? 'chat_read' : (isDelivered ? 'chat_delivered' : '')) iconSize: ChatStyle.entry.message.outgoing.sendIconSize MouseArea { id:retryAction anchors.fill: parent visible: iconId.isError || $chatEntry.status === ChatModel.MessageStatusIdle onClicked: proxyModel.resendMessage(index) } TooltipArea { id:tooltip text: iconId.isError ? qsTr('messageError') : (isRead ? qsTr('messageRead') : qsTr('messageDelivered')) hoveringCursor : retryAction.visible?Qt.PointingHandCursor:Qt.ArrowCursor } } } Component { id: indicator Item { anchors.fill: parent BusyIndicator { anchors.centerIn: parent height: ChatStyle.entry.message.outgoing.busyIndicatorSize width: ChatStyle.entry.message.outgoing.busyIndicatorSize } } } Loader { height: ChatStyle.entry.lineHeight width: ChatStyle.entry.message.outgoing.areaSize sourceComponent: $chatEntry.status === ChatModel.MessageStatusInProgress || $chatEntry.status === ChatModel.MessageStatusFileTransferInProgress ? indicator : iconComponent } ActionButton { height: ChatStyle.entry.lineHeight icon: 'delete' iconSize: ChatStyle.entry.deleteIconSize visible: isHoverEntry() onClicked: removeEntry() } } } } linphone-desktop-4.2.5/linphone-app/ui/modules/Linphone/Codecs/000077500000000000000000000000001376717241300244535ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/ui/modules/Linphone/Codecs/CodecAttribute.qml000066400000000000000000000004211376717241300300640ustar00rootroot00000000000000import QtQuick 2.7 import Linphone.Styles 1.0 // ============================================================================= Text { color: CodecsViewerStyle.attribute.text.color elide: Text.ElideRight font.pointSize: CodecsViewerStyle.attribute.text.pointSize } linphone-desktop-4.2.5/linphone-app/ui/modules/Linphone/Codecs/CodecLegend.qml000066400000000000000000000004331376717241300273220ustar00rootroot00000000000000import QtQuick 2.7 import Linphone.Styles 1.0 // ============================================================================= Text { color: CodecsViewerStyle.legend.color elide: Text.ElideRight font { bold: true pointSize: CodecsViewerStyle.legend.pointSize } } linphone-desktop-4.2.5/linphone-app/ui/modules/Linphone/Codecs/CodecsViewer.qml000066400000000000000000000131041376717241300275470ustar00rootroot00000000000000import QtQml.Models 2.2 import QtQuick 2.7 import QtQuick.Layouts 1.3 import Common 1.0 import Linphone.Styles 1.0 // ============================================================================= Column { id: codecsViewer // --------------------------------------------------------------------------- property alias model: view.model // --------------------------------------------------------------------------- signal downloadRequested (var codecInfo) // --------------------------------------------------------------------------- // Header. // --------------------------------------------------------------------------- RowLayout { anchors { left: parent.left leftMargin: CodecsViewerStyle.leftMargin right: parent.right } height: CodecsViewerStyle.legend.height spacing: CodecsViewerStyle.column.spacing CodecLegend { Layout.preferredWidth: CodecsViewerStyle.column.mimeWidth text: qsTr('codecMime') } CodecLegend { Layout.preferredWidth: CodecsViewerStyle.column.encoderDescriptionWidth text: qsTr('codecEncoderDescription') } CodecLegend { Layout.preferredWidth: CodecsViewerStyle.column.clockRateWidth text: qsTr('codecEncoderClockRate') } CodecLegend { Layout.preferredWidth: CodecsViewerStyle.column.bitrateWidth text: qsTr('codecBitrate') } CodecLegend { Layout.preferredWidth: CodecsViewerStyle.column.recvFmtpWidth text: qsTr('codecRecvFmtp') } CodecLegend { Layout.fillWidth: true Layout.leftMargin: 10 text: qsTr('codecStatus') } } // --------------------------------------------------------------------------- // Codecs. // --------------------------------------------------------------------------- ListView { id: view boundsBehavior: Flickable.StopAtBounds clip: true spacing: 0 anchors { left: parent.left right: parent.right } height: count * CodecsViewerStyle.attribute.height // ------------------------------------------------------------------------- // One codec. // ------------------------------------------------------------------------- delegate: MouseArea { id: dragArea cursorShape: Qt.ArrowCursor property bool held: false anchors { left: parent.left right: parent.right } drag { axis: Drag.YAxis maximumY: (view.count - index) * height - height / 2 minimumY: -index * height - height / 2 target: held ? content : undefined } height: CodecsViewerStyle.attribute.height onPressed: held = true onReleased: { held = false view.model.moveCodec(index, index + 1 + content.y / height) content.y = 0 } Rectangle { id: content readonly property bool isDownloadable: Boolean($codec.downloadUrl) Drag.active: dragArea.held Drag.source: dragArea Drag.hotSpot.x: width / 2 Drag.hotSpot.y: height / 2 anchors { left: parent.left right: parent.right } color: CodecsViewerStyle.attribute.background.color.normal height: dragArea.height RowLayout { anchors { fill: parent leftMargin: CodecsViewerStyle.leftMargin } spacing: CodecsViewerStyle.column.spacing CodecAttribute { Layout.preferredWidth: CodecsViewerStyle.column.mimeWidth text: $codec.mime } CodecAttribute { Layout.preferredWidth: CodecsViewerStyle.column.encoderDescriptionWidth text: $codec.encoderDescription || '' } CodecAttribute { Layout.preferredWidth: CodecsViewerStyle.column.clockRateWidth text: $codec.clockRate || '' } NumericField { Layout.preferredWidth: CodecsViewerStyle.column.bitrateWidth readOnly: content.isDownloadable || !$codec.isVbr text: $codec.bitrate || '' onEditingFinished: view.model.setBitrate(index, text) } TextField { Layout.preferredWidth: CodecsViewerStyle.column.recvFmtpWidth readOnly: content.isDownloadable text: $codec.recvFmtp || '' onEditingFinished: view.model.setRecvFmtp(index, text) } Switch { Layout.fillWidth: true checked: Boolean($codec.enabled) onClicked: !checked && content.isDownloadable ? downloadRequested($codec) : view.model.enableCodec(index, !checked) } } } MouseArea { id: mouseArea anchors.fill: parent cursorShape: Qt.ArrowCursor onPressed: mouse.accepted = false } // --------------------------------------------------------------------- // Animations/States codec. // --------------------------------------------------------------------- states: [ State { when: mouseArea.containsMouse && !dragArea.held PropertyChanges { target: content color: CodecsViewerStyle.attribute.background.color.hovered } }, State { when: dragArea.held PropertyChanges { target: content color: CodecsViewerStyle.attribute.background.color.hovered } PropertyChanges { target: dragArea opacity: 0.5 z: Constants.zMax } } ] } } } linphone-desktop-4.2.5/linphone-app/ui/modules/Linphone/Contact/000077500000000000000000000000001376717241300246465ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/ui/modules/Linphone/Contact/Avatar.qml000066400000000000000000000033741376717241300266060ustar00rootroot00000000000000import QtQuick 2.7 import Common 1.0 import Linphone 1.0 import Linphone.Styles 1.0 // ============================================================================= Item { id: avatar // --------------------------------------------------------------------------- property alias presenceLevel: presenceLevel.level property color backgroundColor: AvatarStyle.backgroundColor property color foregroundColor: 'transparent' property string username property var image property var _initialsRegex: /^\s*([^\s\.]+)(?:[\s\.]+([^\s\.]+))?/ // --------------------------------------------------------------------------- function isLoaded () { return roundedImage.status === Image.Ready } function _computeInitials () { var result = username.match(_initialsRegex) if (!result) { return '' } return result[1].charAt(0).toUpperCase() + ( result[2] != null ? result[2].charAt(0).toUpperCase() : '' ) } // --------------------------------------------------------------------------- RoundedImage { id: roundedImage anchors.fill: parent backgroundColor: avatar.backgroundColor foregroundColor: avatar.foregroundColor source: avatar.image || '' } Text { anchors.centerIn: parent color: AvatarStyle.initials.color font.pointSize: { var width if (parent.width > 0) { width = parent.width / AvatarStyle.initials.ratio } return AvatarStyle.initials.pointSize * (width || 1) } text: _computeInitials() visible: roundedImage.status !== Image.Ready } PresenceLevel { id: presenceLevel anchors { bottom: parent.bottom right: parent.right } height: parent.height / 4 width: parent.width / 4 } } linphone-desktop-4.2.5/linphone-app/ui/modules/Linphone/Contact/Contact.qml000066400000000000000000000035711376717241300267620ustar00rootroot00000000000000import QtQuick 2.7 import QtQuick.Layouts 1.3 import Linphone 1.0 import LinphoneUtils 1.0 import Linphone.Styles 1.0 // ============================================================================= Rectangle { id: item // --------------------------------------------------------------------------- property alias sipAddressColor: description.sipAddressColor property alias usernameColor: description.usernameColor property bool displayUnreadMessageCount: false // A entry from `SipAddressesModel` or an `SipAddressObserver`. property var entry readonly property var _contact: entry.contact // --------------------------------------------------------------------------- color: 'transparent' // No color by default. height: ContactStyle.height RowLayout { anchors { fill: parent leftMargin: ContactStyle.leftMargin rightMargin: ContactStyle.rightMargin } spacing: 0 Avatar { id: avatar Layout.preferredHeight: ContactStyle.contentHeight Layout.preferredWidth: ContactStyle.contentHeight image: _contact && _contact.vcard.avatar presenceLevel: entry.presenceStatus != null ? Presence.getPresenceLevel(entry.presenceStatus) : -1 username: LinphoneUtils.getContactUsername(_contact || entry.sipAddress || entry.fullPeerAddress || entry.peerAddress || '') } ContactDescription { id: description Layout.fillHeight: true Layout.fillWidth: true Layout.leftMargin: ContactStyle.spacing sipAddress: entry.sipAddress || entry.fullPeerAddress || entry.peerAddress || '' username: avatar.username } ContactMessageCounter { Layout.alignment: Qt.AlignTop count: Number(entry.unreadMessageCount) + Number(entry.missedCallCount) isComposing: Boolean(entry.isComposing) visible: item.displayUnreadMessageCount } } } linphone-desktop-4.2.5/linphone-app/ui/modules/Linphone/Contact/ContactDescription.qml000066400000000000000000000023701376717241300311620ustar00rootroot00000000000000import QtQuick 2.7 import Linphone 1.0 import Linphone.Styles 1.0 // ============================================================================= Column { property alias username: username.text property string sipAddress property color sipAddressColor: ContactDescriptionStyle.sipAddress.color property color usernameColor: ContactDescriptionStyle.username.color property int horizontalTextAlignment // --------------------------------------------------------------------------- Text { id: username color: usernameColor elide: Text.ElideRight font.bold: true font.pointSize: ContactDescriptionStyle.username.pointSize horizontalAlignment: horizontalTextAlignment verticalAlignment: Text.AlignBottom width: parent.width height: (parent.height-parent.topPadding-parent.bottomPadding)/parent.visibleChildren.length } Text { text: SipAddressesModel.cleanSipAddress(sipAddress) color: sipAddressColor elide: Text.ElideRight font.pointSize: ContactDescriptionStyle.sipAddress.pointSize horizontalAlignment: horizontalTextAlignment verticalAlignment: Text.AlignTop width: parent.width height: (parent.height-parent.topPadding-parent.bottomPadding)/parent.visibleChildren.length } } linphone-desktop-4.2.5/linphone-app/ui/modules/Linphone/Contact/ContactMessageCounter.qml000066400000000000000000000020451376717241300316220ustar00rootroot00000000000000import QtQuick 2.7 import QtQuick.Layouts 1.3 import Common 1.0 import Linphone 1.0 import Linphone.Styles 1.0 // ============================================================================= Item { id: messageCounter property alias count: counterIcon.count property bool isComposing implicitHeight: counterIcon.height + ContactMessageCounterStyle.verticalMargins * 2 implicitWidth: counterIcon.width + ContactMessageCounterStyle.horizontalMargins * 2 MessageCounter { id: counterIcon property int composingIndex: 0 anchors.centerIn: parent icon: messageCounter.isComposing ? ('chat_is_composing_' + counterIcon.composingIndex) : 'chat_count' visible: messageCounter.count > 0 || messageCounter.isComposing Timer { interval: 500 repeat: true running: messageCounter.isComposing onRunningChanged: { if (running) { counterIcon.composingIndex = 0 } } onTriggered: counterIcon.composingIndex = (counterIcon.composingIndex + 1) % 4 } } } linphone-desktop-4.2.5/linphone-app/ui/modules/Linphone/Dialog/000077500000000000000000000000001376717241300244525ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/ui/modules/Linphone/Dialog/OnlineInstallerDialog.qml000066400000000000000000000077231376717241300314200ustar00rootroot00000000000000import QtQuick 2.7 import QtQuick.Controls 2.2 import Common 1.0 import Linphone 1.0 import Linphone.Styles 1.0 import Utils 1.0 // ============================================================================= DialogPlus { id: dialog // --------------------------------------------------------------------------- property alias downloadUrl: fileDownloader.url property alias installFolder: fileDownloader.downloadFolder property string installName // Right install name. property string mime // Human readable name. property bool _installing: false property int _exitStatus: -1 // Not downloaded for the moment. // --------------------------------------------------------------------------- function install () { dialog._installing = true fileDownloader.download() } function _endInstall (exitStatus) { if (exitStatus === 1) { Utils.write(installFolder + mime + '.txt', downloadUrl) } dialog._exitStatus = exitStatus dialog._installing = false } // --------------------------------------------------------------------------- // TODO: Improve one day. Do not launch download directly. // Provide a download function (window.attachVirtualWindow cannot call // function after creation at this moment). Component.onCompleted: dialog.install() // --------------------------------------------------------------------------- buttons: [ // TODO: Add a retry button??? TextButtonB { enabled: !dialog._installing && !fileDownloader.downloading && !fileExtractor.extracting text: qsTr('confirm') onClicked: exit(1) } ] centeredButtons: true descriptionText: { var str if (dialog.extracting) { str = qsTr('onlineInstallerExtractingDescription') } else if (dialog._installing) { str = qsTr('onlineInstallerDownloadingDescription') } else if (dialog._exitStatus > 0) { str = qsTr('onlineInstallerFinishedDescription') } else { str = qsTr('onlineInstallerFailedDescription') } return str.replace('%1', dialog.mime) } height: OnlineInstallerDialogStyle.height width: OnlineInstallerDialogStyle.width Column { anchors.verticalCenter: parent.verticalCenter width: parent.width spacing: OnlineInstallerDialogStyle.column.spacing ProgressBar { id: progressBar property var target: fileDownloader height: OnlineInstallerDialogStyle.column.bar.height width: parent.width to: target.totalBytes value: target.readBytes indeterminate : true background: Rectangle { color: OnlineInstallerDialogStyle.column.bar.background.color radius: OnlineInstallerDialogStyle.column.bar.radius } contentItem: Item { Rectangle { color: dialog._exitStatus ? OnlineInstallerDialogStyle.column.bar.contentItem.color.normal : OnlineInstallerDialogStyle.column.bar.contentItem.color.failed height: parent.height radius: OnlineInstallerDialogStyle.column.bar.radius width: progressBar.visualPosition * parent.width } } } Text { anchors.right: parent.right color: OnlineInstallerDialogStyle.column.text.color font.pointSize: OnlineInstallerDialogStyle.column.text.pointSize text: { var target = progressBar.target var fileSize = Utils.formatSize(target.totalBytes) return Utils.formatSize(target.readBytes) + '/' + fileSize } } FileDownloader { id: fileDownloader onDownloadFailed: dialog._endInstall(0) onDownloadFinished: { fileExtractor.file = filePath progressBar.target = fileExtractor fileExtractor.extract() } } FileExtractor { id: fileExtractor extractFolder: dialog.installFolder extractName: dialog.installName onExtractFailed: {fileDownloader.remove(); dialog._endInstall(0)} onExtractFinished: {fileDownloader.remove(); dialog._endInstall(1)} } } } linphone-desktop-4.2.5/linphone-app/ui/modules/Linphone/History/000077500000000000000000000000001376717241300247145ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/ui/modules/Linphone/History/Event.qml000066400000000000000000000060311376717241300265100ustar00rootroot00000000000000import QtQuick 2.7 import Common 1.0 import Linphone 1.0 import LinphoneUtils 1.0 import Linphone.Styles 1.0 import Utils 1.0 // ============================================================================= Row { signal entryClicked(string sipAddress) readonly property var _sipAddressObserver: SipAddressesModel.getSipAddressObserver($historyEntry.sipAddress, '') property string _type: { var status = $historyEntry.status if (status === HistoryModel.CallStatusSuccess) { if (!$historyEntry.isStart) { return 'ended_call' } return $historyEntry.isOutgoing ? 'outgoing_call' : 'incoming_call' } if (status === HistoryModel.CallStatusDeclined) { return $historyEntry.isOutgoing ? 'declined_outgoing_call' : 'declined_incoming_call' } if (status === HistoryModel.CallStatusMissed) { return $historyEntry.isOutgoing ? 'missed_outgoing_call' : 'missed_incoming_call' } if (status === HistoryModel.CallStatusAborted) { return $historyEntry.isOutgoing ? 'outgoing_call' : 'incoming_call' } if (status === HistoryModel.CallStatusEarlyAborted) { return $historyEntry.isOutgoing ? 'missed_outgoing_call' : 'missed_incoming_call' } if (status === HistoryModel.CallStatusAcceptedElsewhere) { return $historyEntry.isOutgoing ? 'outgoing_call' : 'incoming_call' } if (status === HistoryModel.CallStatusDeclinedElsewhere) { return $historyEntry.isOutgoing ? 'declined_outgoing_call' : 'declined_incoming_call' } return 'unknown_call_event' } height: HistoryStyle.entry.lineHeight spacing: HistoryStyle.entry.message.extraContent.spacing Icon { height: parent.height icon: _type iconSize: HistoryStyle.entry.event.iconSize width: HistoryStyle.entry.metaWidth } Text { Component { // Never created. // Private data for `lupdate`. Item { property var i18n: [ QT_TR_NOOP('declinedIncomingCall'), QT_TR_NOOP('declinedOutgoingCall'), QT_TR_NOOP('endedCall'), QT_TR_NOOP('incomingCall'), QT_TR_NOOP('missedIncomingCall'), QT_TR_NOOP('missedOutgoingCall'), QT_TR_NOOP('outgoingCall') ] } } color: HistoryStyle.entry.event.text.color font { bold: true pointSize: HistoryStyle.entry.event.text.pointSize } height: parent.height text: qsTr(Utils.snakeToCamel(_type)) +' - ' verticalAlignment: Text.AlignVCenter } Text { color: HistoryStyle.entry.event.text.color font { bold: true pointSize: HistoryStyle.entry.event.text.pointSize } height: parent.height text: LinphoneUtils.getContactUsername(_sipAddressObserver) verticalAlignment: Text.AlignVCenter MouseArea{ anchors.fill:parent onClicked:entryClicked($historyEntry.sipAddress) } } ActionButton { height: HistoryStyle.entry.lineHeight icon: 'delete' iconSize: HistoryStyle.entry.deleteIconSize visible: isHoverEntry() onClicked: removeEntry() } } linphone-desktop-4.2.5/linphone-app/ui/modules/Linphone/History/History.js000066400000000000000000000036671376717241300267270ustar00rootroot00000000000000/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ // ============================================================================= // `Chat.qml` Logic. // ============================================================================= .import QtQuick 2.7 as QtQuick .import Linphone 1.0 as Linphone .import 'qrc:/ui/scripts/LinphoneUtils/linphone-utils.js' as LinphoneUtils // ============================================================================= function initView () { history.tryToLoadMoreEntries = false history.bindToEnd = true } function loadMoreEntries () { if (history.atYBeginning && !history.tryToLoadMoreEntries) { history.tryToLoadMoreEntries = true history.positionViewAtBeginning() container.proxyModel.loadMoreEntries() } } function getComponentFromEntry (historyEntry) { if (historyEntry.type === Linphone.HistoryModel.CallEntry) { return 'Event.qml' } return '' } function handleMoreEntriesLoaded (n) { history.positionViewAtIndex(n - 1, QtQuick.ListView.Beginning) history.tryToLoadMoreEntries = false } function handleMovementEnded () { if (history.atYEnd) { history.bindToEnd = true } } function handleMovementStarted () { history.bindToEnd = false } linphone-desktop-4.2.5/linphone-app/ui/modules/Linphone/History/History.qml000066400000000000000000000134711376717241300270760ustar00rootroot00000000000000import QtQuick 2.7 import QtQuick.Controls 2.2 import QtQuick.Layouts 1.3 import Common 1.0 import Linphone 1.0 import Linphone.Styles 1.0 import 'History.js' as Logic // ============================================================================= Rectangle { id: container property alias proxyModel: history.model signal entryClicked(string sipAddress) // --------------------------------------------------------------------------- color: HistoryStyle.color ColumnLayout { anchors.fill: parent spacing: 0 ScrollableListView { id: history // ----------------------------------------------------------------------- property bool bindToEnd: false property bool tryToLoadMoreEntries: true // ----------------------------------------------------------------------- Layout.fillHeight: true Layout.fillWidth: true highlightFollowsCurrentItem: false section { criteria: ViewSection.FullString delegate: sectionHeading property: '$sectionDate' } // ----------------------------------------------------------------------- Component.onCompleted: Logic.initView() onContentYChanged: Logic.loadMoreEntries() onMovementEnded: Logic.handleMovementEnded() onMovementStarted: Logic.handleMovementStarted() // ----------------------------------------------------------------------- Connections { target: proxyModel // When the view is changed (for example `Calls` -> `Messages`), // the position is set at end and it can be possible to load // more entries. onEntryTypeFilterChanged: Logic.initView() onMoreEntriesLoaded: Logic.handleMoreEntriesLoaded(n) } // ----------------------------------------------------------------------- // Heading. // ----------------------------------------------------------------------- Component { id: sectionHeading Item { implicitHeight: container.height + HistoryStyle.sectionHeading.bottomMargin width: parent.width Borders { id: container borderColor: HistoryStyle.sectionHeading.border.color bottomWidth: HistoryStyle.sectionHeading.border.width implicitHeight: text.contentHeight + HistoryStyle.sectionHeading.padding * 2 + HistoryStyle.sectionHeading.border.width * 2 topWidth: HistoryStyle.sectionHeading.border.width width: parent.width Text { id: text anchors.fill: parent color: HistoryStyle.sectionHeading.text.color font { bold: true pointSize: HistoryStyle.sectionHeading.text.pointSize } horizontalAlignment: Text.AlignHCenter verticalAlignment: Text.AlignVCenter // Cast section to integer because Qt converts the // sectionDate in string!!! text: new Date(section).toLocaleDateString( Qt.locale(App.locale) ) } } } } // ----------------------------------------------------------------------- // Message/Event renderer. // ----------------------------------------------------------------------- delegate: Rectangle { id: entry function isHoverEntry () { return mouseArea.containsMouse } function removeEntry () { proxyModel.removeEntry(index) } anchors { left: parent ? parent.left : undefined leftMargin: HistoryStyle.entry.leftMargin right: parent ? parent.right : undefined rightMargin: HistoryStyle.entry.deleteIconSize + HistoryStyle.entry.message.extraContent.spacing + HistoryStyle.entry.message.extraContent.rightMargin + HistoryStyle.entry.message.extraContent.leftMargin } color: HistoryStyle.color implicitHeight: layout.height + HistoryStyle.entry.bottomMargin // --------------------------------------------------------------------- MouseArea { id: mouseArea cursorShape: Qt.ArrowCursor hoverEnabled: true implicitHeight: layout.height width: parent.width + parent.anchors.rightMargin RowLayout { id: layout spacing: 0 width: entry.width // Display time. Text { Layout.alignment: Qt.AlignTop Layout.preferredHeight: HistoryStyle.entry.lineHeight Layout.preferredWidth: HistoryStyle.entry.time.width color: HistoryStyle.entry.time.color font.pointSize: HistoryStyle.entry.time.pointSize text: $historyEntry.timestamp.toLocaleString( Qt.locale(App.locale), 'hh:mm' ) verticalAlignment: Text.AlignVCenter TooltipArea { text: $historyEntry.timestamp.toLocaleString(Qt.locale(App.locale)) } } // Display content. Loader { id:entryLoader Layout.fillWidth: true source: Logic.getComponentFromEntry($historyEntry) } Connections{ target:entryLoader.item onEntryClicked:{entryClicked(sipAddress)} } } } } } } // --------------------------------------------------------------------------- // Scroll at end if necessary. // --------------------------------------------------------------------------- Timer { interval: 100 repeat: true running: true onTriggered: history.bindToEnd && history.positionViewAtEnd() } } linphone-desktop-4.2.5/linphone-app/ui/modules/Linphone/Menus/000077500000000000000000000000001376717241300243425ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/ui/modules/Linphone/Menus/SipAddressesMenu.qml000066400000000000000000000052341376717241300302770ustar00rootroot00000000000000import QtQuick 2.7 import Common 1.0 import Linphone.Styles 1.0 // ============================================================================= Item { id: sipAddressesMenu // --------------------------------------------------------------------------- property alias relativeTo: menu.relativeTo property alias relativeX: menu.relativeX property alias relativeY: menu.relativeY property var sipAddresses: [] // --------------------------------------------------------------------------- function open () { var length = sipAddresses.length if (!length) { return } if (length === 1) { return sipAddressesMenu.sipAddressClicked(sipAddresses[0]) } menu.open() } function _fillModel () { model.clear() sipAddresses.forEach(function (sipAddress) { model.append({ $sipAddress: sipAddress }) }) } // --------------------------------------------------------------------------- signal sipAddressClicked (string sipAddress) // --------------------------------------------------------------------------- onSipAddressesChanged: _fillModel() // --------------------------------------------------------------------------- DropDownDynamicMenu { id: menu parent: sipAddressesMenu.parent entryHeight: SipAddressesMenuStyle.entry.height maxMenuHeight: SipAddressesMenuStyle.maxHeight ScrollableListView { id: list spacing: SipAddressesMenuStyle.spacing width: SipAddressesMenuStyle.entry.width model: ListModel { id: model Component.onCompleted: _fillModel() } delegate: Rectangle { height: menu.entryHeight width: parent.width color: mouseArea.pressed ? SipAddressesMenuStyle.entry.color.pressed : ( mouseArea.containsMouse ? SipAddressesMenuStyle.entry.color.hovered : SipAddressesMenuStyle.entry.color.normal ) Text { anchors { left: parent.left leftMargin: SipAddressesMenuStyle.entry.leftMargin right: parent.right rightMargin: SipAddressesMenuStyle.entry.rightMargin } color: SipAddressesMenuStyle.entry.text.color elide: Text.ElideRight font.pointSize: SipAddressesMenuStyle.entry.text.pointSize height: parent.height text: $sipAddress verticalAlignment: Text.AlignVCenter } MouseArea { id: mouseArea anchors.fill: parent onClicked: { menu.close() sipAddressesMenu.sipAddressClicked($sipAddress) } } } } } } linphone-desktop-4.2.5/linphone-app/ui/modules/Linphone/Misc/000077500000000000000000000000001376717241300241465ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/ui/modules/Linphone/Misc/MessageCounter.qml000066400000000000000000000013111376717241300276010ustar00rootroot00000000000000import QtQuick 2.7 import Common 1.0 import Linphone.Styles 1.0 // ============================================================================= Icon { id: messageCounter property int count: 0 icon: 'chat_count' iconSize: MessageCounterStyle.iconSize.message visible: messageCounter.count > 0 Icon { anchors { horizontalCenter: parent.right verticalCenter: parent.bottom } icon: 'chat_amount' iconSize: MessageCounterStyle.iconSize.amount visible: messageCounter.count > 0 Text { anchors.centerIn: parent color: MessageCounterStyle.text.color font.pointSize: MessageCounterStyle.text.pointSize text: messageCounter.count } } } linphone-desktop-4.2.5/linphone-app/ui/modules/Linphone/Notifications/000077500000000000000000000000001376717241300260645ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/ui/modules/Linphone/Notifications/Notification.qml000066400000000000000000000016751376717241300312360ustar00rootroot00000000000000import QtQuick 2.7 import Common 1.0 import Linphone.Styles 1.0 // ============================================================================= DesktopPopup { id: notification property alias icon: iconSign.icon property var notificationData: ({}) property int overrodeHeight default property alias _content: content.data signal deleteNotification (var notification) function _close (cb) { if (cb) { cb() } deleteNotification(notification) } Rectangle { color: NotificationStyle.color height: overrodeHeight || NotificationStyle.height width: NotificationStyle.width border { color: NotificationStyle.border.color width: NotificationStyle.border.width } Item { id: content anchors.fill: parent } Icon { id: iconSign anchors { left: parent.left top: parent.top } iconSize: NotificationStyle.iconSize } } } linphone-desktop-4.2.5/linphone-app/ui/modules/Linphone/Notifications/Notification.spec.qml000066400000000000000000000021131376717241300321530ustar00rootroot00000000000000import QtTest 1.1 import Linphone 1.0 import Utils 1.0 // ============================================================================= // Check defined properties/methods used in `Notifier.cpp`. TestCase { Notification { id: notification } function test_notificationDataProperty () { compare(Utils.isObject(notification.notificationData), true) } function test_notificationPopupX () { compare(Utils.isInteger(notification.popupX), true) } function test_notificationPopupY () { compare(Utils.isInteger(notification.popupY), true) } function test_notificationPopupHeight () { compare(Utils.isInteger(notification.popupHeight), true) } function test_notificationPopupWidth () { compare(Utils.isInteger(notification.popupWidth), true) } function test_notificationOpenMethod () { compare(Utils.isFunction(notification.open), true) } function test_childWindow () { var window = notification.data[0] compare(Utils.qmlTypeof(window, 'QQuickWindowQmlImpl'), true) compare(window.objectName === '__internalWindow', true) } } linphone-desktop-4.2.5/linphone-app/ui/modules/Linphone/Notifications/NotificationBasic.qml000066400000000000000000000017371376717241300321770ustar00rootroot00000000000000import QtQuick 2.7 import Common 1.0 import Linphone.Styles 1.0 // ============================================================================= Notification { id: notification property string message property var handler: (function () {}) overrodeHeight: NotificationBasicStyle.overrodeHeight // --------------------------------------------------------------------------- Loader { active: Boolean(notification.message) anchors { fill: parent leftMargin: NotificationBasicStyle.leftMargin rightMargin: NotificationBasicStyle.rightMargin } sourceComponent: Text { anchors.fill: parent color: NotificationBasicStyle.message.color font.pointSize: NotificationBasicStyle.message.pointSize text: notification.message verticalAlignment: Text.AlignVCenter wrapMode: Text.Wrap MouseArea { anchors.fill: parent onClicked: notification._close(notification.handler) } } } } NotificationNewVersionAvailable.qml000066400000000000000000000002721376717241300347700ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/ui/modules/Linphone/NotificationsNotificationBasic { icon: 'update_sign' message: notificationData.message?notificationData.message:'' handler: (function () { Qt.openUrlExternally(notificationData.url) }) } linphone-desktop-4.2.5/linphone-app/ui/modules/Linphone/Notifications/NotificationReceivedCall.qml000066400000000000000000000044541376717241300334770ustar00rootroot00000000000000import QtQuick 2.7 import QtQuick.Layouts 1.3 import Common 1.0 import Linphone 1.0 import Linphone.Styles 1.0 // ============================================================================= Notification { id: notification icon: 'call_sign_incoming' // --------------------------------------------------------------------------- readonly property var call: notificationData && notificationData.call // --------------------------------------------------------------------------- Loader { active: Boolean(notification.call) anchors { fill: parent leftMargin: NotificationReceivedCallStyle.leftMargin rightMargin: NotificationReceivedCallStyle.rightMargin bottomMargin: NotificationReceivedCallStyle.bottomMargin } sourceComponent: ColumnLayout { spacing: NotificationReceivedCallStyle.spacing Contact { Layout.fillWidth: true entry: { var call = notification.call return SipAddressesModel.getSipAddressObserver(call ? call.fullPeerAddress : '', call ? call.fullLocalAddress : '') } } // --------------------------------------------------------------------- // Action buttons. // --------------------------------------------------------------------- Item { Layout.fillHeight: true Layout.fillWidth: true ActionBar { id: acceptActionBar anchors.centerIn: parent iconSize: NotificationReceivedCallStyle.actionArea.iconSize ActionButton { icon: 'video_call_accept' visible: SettingsModel.videoSupported onClicked: notification._close(notification.call.acceptWithVideo) } ActionButton { icon: 'call_accept' onClicked: notification._close(notification.call.accept) } } ActionBar { anchors { right: parent.right rightMargin: NotificationReceivedCallStyle.actionArea.rightButtonsGroupMargin verticalCenter: parent.verticalCenter } iconSize: NotificationReceivedCallStyle.actionArea.iconSize ActionButton { icon: 'hangup' onClicked: notification._close(notification.call.terminate) } } } } } } NotificationReceivedFileMessage.qml000066400000000000000000000044161376717241300347270ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/ui/modules/Linphone/Notificationsimport QtQuick 2.7 import QtQuick.Layouts 1.3 import Common 1.0 import Linphone.Styles 1.0 import Utils 1.0 // ============================================================================= Notification { id: notification icon: 'file_sign' overrodeHeight: NotificationReceivedFileMessageStyle.overrodeHeight // --------------------------------------------------------------------------- readonly property string fileUri: notificationData && notificationData.fileUri || '' readonly property string imageUri: notificationData && notificationData.imageUri || '' // --------------------------------------------------------------------------- Loader { active: Boolean(notification.fileUri) anchors { fill: parent leftMargin: NotificationReceivedFileMessageStyle.leftMargin rightMargin: NotificationReceivedFileMessageStyle.rightMargin } sourceComponent: RowLayout { anchors.fill: parent spacing: NotificationReceivedFileMessageStyle.spacing Text { Layout.fillWidth: true color: NotificationReceivedFileMessageStyle.fileName.color elide: Text.ElideRight font.pointSize: NotificationReceivedFileMessageStyle.fileName.pointSize text: Utils.basename(notification.fileUri) visible:!image.visible } Image{ id:image mipmap: Qt.platform.os === 'osx' Layout.fillHeight: true Layout.fillWidth: true fillMode: Image.PreserveAspectFit source: (imageUri ?"image://external/"+notification.imageUri : '') visible: image.status == Image.Ready } Text { Layout.preferredWidth: NotificationReceivedFileMessageStyle.fileSize.width color: NotificationReceivedFileMessageStyle.fileSize.color elide: Text.ElideRight font.pointSize: NotificationReceivedFileMessageStyle.fileSize.pointSize horizontalAlignment: Text.AlignRight text: Utils.formatSize(notification.notificationData.fileSize) } } MouseArea { anchors.fill: parent onClicked: notification._close(function () { var uri = Utils.getUriFromSystemPath(notification.fileUri) if (!Qt.openUrlExternally(uri)) { Qt.openUrlExternally(Utils.dirname(uri)) } }) } } } NotificationReceivedMessage.qml000066400000000000000000000051761376717241300341330ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/ui/modules/Linphone/Notificationsimport QtQuick 2.7 import QtQuick.Layouts 1.3 import Common 1.0 import Linphone 1.0 import Linphone.Styles 1.0 // ============================================================================= Notification { id: notification icon: 'message_sign' // --------------------------------------------------------------------------- readonly property string peerAddress: notificationData && notificationData.peerAddress || '' readonly property string localAddress: notificationData && notificationData.localAddress || '' readonly property string fullPeerAddress: notificationData && notificationData.fullPeerAddress || '' readonly property string fullLocalAddress: notificationData && notificationData.fullLocalAddress || '' // --------------------------------------------------------------------------- Loader { active: Boolean(notification.peerAddress) && Boolean(notification.localAddress) anchors { fill: parent leftMargin: NotificationReceivedMessageStyle.leftMargin rightMargin: NotificationReceivedMessageStyle.rightMargin bottomMargin: NotificationReceivedMessageStyle.bottomMargin } sourceComponent: ColumnLayout { spacing: NotificationReceivedMessageStyle.spacing Contact { Layout.fillWidth: true entry: SipAddressesModel.getSipAddressObserver(notification.fullPeerAddress, notification.fullLocalAddress) } Rectangle { Layout.fillHeight: true Layout.fillWidth: true color: NotificationReceivedMessageStyle.messageContainer.color radius: NotificationReceivedMessageStyle.messageContainer.radius Text { anchors { fill: parent margins: NotificationReceivedMessageStyle.messageContainer.margins } color: NotificationReceivedMessageStyle.messageContainer.text.color elide: Text.ElideRight font { italic: true pointSize: NotificationReceivedMessageStyle.messageContainer.text.pointSize } verticalAlignment: Text.AlignVCenter text: notification.notificationData.message wrapMode: Text.Wrap } } } } MouseArea { anchors.fill: parent onClicked: notification._close(function () { AccountSettingsModel.setDefaultProxyConfigFromSipAddress(notification.localAddress) notification.notificationData.window.setView('Conversation', { peerAddress: notification.peerAddress, localAddress: notification.localAddress, fullPeerAddress: notification.fullPeerAddress, fullLocalAddress: notification.fullLocalAddress }) }) } } NotificationRecordingCompleted.qml000066400000000000000000000005221376717241300346370ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/ui/modules/Linphone/Notificationsimport Utils 1.0 // ============================================================================= NotificationBasic { icon: 'recording_sign' message: Utils.basename(notificationData.filePath) handler: (function () { Qt.openUrlExternally(Utils.dirname( Utils.getUriFromSystemPath(notificationData.filePath) )) }) } NotificationSnapshotWasTaken.qml000066400000000000000000000005211376717241300343220ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/ui/modules/Linphone/Notificationsimport Utils 1.0 // ============================================================================= NotificationBasic { icon: 'snapshot_sign' message: Utils.basename(notificationData.filePath) handler: (function () { Qt.openUrlExternally(Utils.dirname( Utils.getUriFromSystemPath(notificationData.filePath) )) }) } linphone-desktop-4.2.5/linphone-app/ui/modules/Linphone/Presence/000077500000000000000000000000001376717241300250175ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/ui/modules/Linphone/Presence/PresenceLevel.qml000066400000000000000000000006741376717241300302750ustar00rootroot00000000000000import QtQuick 2.7 import Common 1.0 import Linphone 1.0 // ============================================================================= // Wrapper to use `icon` property. Item { property var level: null Icon { anchors.centerIn: parent icon: (level !== -1 && level != null) ? Presence.getPresenceLevelIconName(level) : '' iconSize: parent.height > parent.width ? parent.width : parent.height } } linphone-desktop-4.2.5/linphone-app/ui/modules/Linphone/SmartSearchBar/000077500000000000000000000000001376717241300261145ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/ui/modules/Linphone/SmartSearchBar/SmartSearchBar.qml000066400000000000000000000042661376717241300315000ustar00rootroot00000000000000import QtQuick 2.7 import Common 1.0 import Linphone 1.0 import Linphone.Styles 1.0 // ============================================================================= SearchBox { id: searchBox // --------------------------------------------------------------------------- readonly property alias isOpen: searchBox._isOpen property alias header : view.headerItem // --------------------------------------------------------------------------- signal addContact (string sipAddress) signal launchChat (string sipAddress) signal launchCall (string sipAddress) signal launchVideoCall (string sipAddress) signal entryClicked (var entry) // --------------------------------------------------------------------------- entryHeight: SipAddressesViewStyle.entry.height // --------------------------------------------------------------------------- onEnterPressed: { var sipAddress = view.interpretableSipAddress return sipAddress.length > 0 && SettingsModel.outgoingCallsEnabled && searchBox.launchCall(sipAddress) } // --------------------------------------------------------------------------- SipAddressesView { id: view actions: [{ icon: 'video_call', handler: function (entry) { searchBox.closeMenu() searchBox.launchVideoCall(entry.sipAddress) }, visible: SettingsModel.videoSupported && SettingsModel.outgoingCallsEnabled }, { icon: 'call', handler: function (entry) { searchBox.closeMenu() searchBox.launchCall(entry.sipAddress) }, visible: SettingsModel.outgoingCallsEnabled }, { icon: SettingsModel.chatEnabled ? 'chat' : 'history', handler: function (entry) { searchBox.closeMenu() searchBox.launchChat(entry.sipAddress) } }] headerButtonDescription: qsTr('addContact') headerButtonIcon: 'contact_add' headerButtonAction: SettingsModel.contactsEnabled && (function (sipAddress) { searchBox.closeMenu() searchBox.addContact(sipAddress) }) genSipAddress: searchBox.filter model: SipAddressesProxyModel {} onEntryClicked: { searchBox.closeMenu() searchBox.entryClicked(entry) } } } linphone-desktop-4.2.5/linphone-app/ui/modules/Linphone/Styles/000077500000000000000000000000001376717241300245365ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/ui/modules/Linphone/Styles/Account/000077500000000000000000000000001376717241300261325ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/ui/modules/Linphone/Styles/Account/AccountStatusStyle.qml000066400000000000000000000010601376717241300324630ustar00rootroot00000000000000pragma Singleton import QtQml 2.2 import Colors 1.0 import Units 1.0 // ============================================================================= QtObject { property int horizontalSpacing: 6 property QtObject presenceLevel: QtObject { property int bottomMargin: 2 property int size: 16 } property QtObject sipAddress: QtObject { property color color: Colors.g property int pointSize: Units.dp * 10 } property QtObject username: QtObject { property color color: Colors.j property int pointSize: Units.dp * 11 } } linphone-desktop-4.2.5/linphone-app/ui/modules/Linphone/Styles/Blocks/000077500000000000000000000000001376717241300257535ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/ui/modules/Linphone/Styles/Blocks/CardBlockStyle.qml000066400000000000000000000013331376717241300313330ustar00rootroot00000000000000pragma Singleton import QtQml 2.2 import Colors 1.0 import Units 1.0 // ============================================================================= QtObject { property int spacing: 30 property int width: 200 property QtObject content: QtObject { property int height: 40 } property QtObject description: QtObject { property color color: Colors.n property int pointSize: Units.dp * 10 property int height: 40 } property QtObject icon: QtObject { property int bottomMargin: 20 property int size: 148 } property QtObject title: QtObject { property color color: Colors.j property int bottomMargin: 10 property int pointSize: Units.dp * 10 property int height: 20 } } linphone-desktop-4.2.5/linphone-app/ui/modules/Linphone/Styles/Blocks/RequestBlockStyle.qml000066400000000000000000000007051376717241300321140ustar00rootroot00000000000000pragma Singleton import QtQml 2.2 import Colors 1.0 import Units 1.0 // ============================================================================= QtObject { property int height: 60 property QtObject error: QtObject { property color color: Colors.error property int pointSize: Units.dp * 11 property int padding: 4 } property QtObject loadingIndicator: QtObject { property int height: 20 property int width: 20 } } linphone-desktop-4.2.5/linphone-app/ui/modules/Linphone/Styles/Calls/000077500000000000000000000000001376717241300255745ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/ui/modules/Linphone/Styles/Calls/CallControlsStyle.qml000066400000000000000000000004511376717241300317270ustar00rootroot00000000000000pragma Singleton import QtQml 2.2 import Colors 1.0 // ============================================================================= QtObject { property color color: Colors.e property int height: 60 property int leftMargin: 12 property int rightMargin: 12 property int signSize: 40 } linphone-desktop-4.2.5/linphone-app/ui/modules/Linphone/Styles/Calls/CallStatisticsStyle.qml000066400000000000000000000013721376717241300322610ustar00rootroot00000000000000pragma Singleton import QtQml 2.2 import Colors 1.0 import Units 1.0 // ============================================================================= QtObject { property color color: Colors.e property int height: 280 property int leftMargin: 12 property int rightMargin: 12 property int spacing: 8 property int topMargin: 10 property QtObject title: QtObject { property color color: Colors.d property int bottomMargin: 20 property int pointSize: Units.dp * 16 } property QtObject key: QtObject { property color color: Colors.d property int pointSize: Units.dp * 10 property int width: 200 } property QtObject value: QtObject { property color color: Colors.d property int pointSize: Units.dp * 10 } } linphone-desktop-4.2.5/linphone-app/ui/modules/Linphone/Styles/Calls/CallsStyle.qml000066400000000000000000000015471376717241300303750ustar00rootroot00000000000000pragma Singleton import QtQml 2.2 import Colors 1.0 // ============================================================================= QtObject { property QtObject entry: QtObject { property int iconActionSize: 35 property int iconMenuSize: 17 property int height: 30 property int width: 200 property QtObject color: QtObject { property color normal: Colors.e property color selected: Colors.j } property QtObject endCallAnimation: QtObject { property color blinkColor: Colors.i property int duration: 300 property int loops: 3 } property QtObject sipAddressColor: QtObject { property color normal: Colors.n property color selected: Colors.q } property QtObject usernameColor: QtObject { property color normal: Colors.j property color selected: Colors.q } } } linphone-desktop-4.2.5/linphone-app/ui/modules/Linphone/Styles/Calls/ConferenceControlsStyle.qml000066400000000000000000000004151376717241300331230ustar00rootroot00000000000000pragma Singleton import QtQml 2.2 import Colors 1.0 // ============================================================================= QtObject { property color color: Colors.e property int height: 60 property int leftMargin: 12 property int rightMargin: 12 } linphone-desktop-4.2.5/linphone-app/ui/modules/Linphone/Styles/Chat/000077500000000000000000000000001376717241300254155ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/ui/modules/Linphone/Styles/Chat/ChatStyle.qml000066400000000000000000000067451376717241300300440ustar00rootroot00000000000000pragma Singleton import QtQml 2.2 import Colors 1.0 import Units 1.0 // ============================================================================= QtObject { property color color: Colors.q property QtObject sectionHeading: QtObject { property int padding: 5 property int bottomMargin: 20 property QtObject border: QtObject { property color color: Colors.g10 property int width: 1 } property QtObject text: QtObject { property int pointSize: Units.dp * 10 property color color: Colors.g } } property QtObject sendArea: QtObject { property int height: 80 property QtObject border: QtObject { property color color: Colors.f property int width: 1 } } property QtObject composingText: QtObject { property color color: Colors.d property int height: 25 property int leftPadding: 20 property int pointSize: Units.dp * 9 } property QtObject entry: QtObject { property int bottomMargin: 10 property int deleteIconSize: 22 property int leftMargin: 18 property int lineHeight: 30 property int metaWidth: 40 property QtObject event: QtObject { property int iconSize: 18 property QtObject text: QtObject { property color color: Colors.d property int pointSize: Units.dp * 10 } } property QtObject message: QtObject { property int padding: 8 property int radius: 4 property QtObject extraContent: QtObject { property int leftMargin: 10 property int spacing: 5 property int rightMargin: 5 } property QtObject file: QtObject { property int height: 64 property int iconSize: 18 property int margins: 8 property int spacing: 8 property int width: 250 property QtObject animation: QtObject { property int duration: 200 property real to: 1.5 } property QtObject extension: QtObject { property QtObject background: QtObject { property color color: Colors.l50 } property QtObject text: QtObject { property color color: Colors.q } } property QtObject status: QtObject { property int spacing: 4 property QtObject bar: QtObject { property int height: 6 property int radius: 3 property QtObject background: QtObject { property color color: Colors.f } property QtObject contentItem: QtObject { property color color: Colors.p } } } } property QtObject images: QtObject { property int height: 48 } property QtObject incoming: QtObject { property color backgroundColor: Colors.o property int avatarSize: 20 property QtObject text: QtObject { property color color: Colors.d property int pointSize: Units.dp * 10 } } property QtObject outgoing: QtObject { property color backgroundColor: Colors.e property int areaSize: 16 property int busyIndicatorSize: 16 property int sendIconSize: 12 property QtObject text: QtObject { property color color: Colors.d property int pointSize: Units.dp * 10 } } } property QtObject time: QtObject { property color color: Colors.d property int pointSize: Units.dp * 10 property int width: 44 } } } linphone-desktop-4.2.5/linphone-app/ui/modules/Linphone/Styles/Codecs/000077500000000000000000000000001376717241300257365ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/ui/modules/Linphone/Styles/Codecs/CodecsViewerStyle.qml000066400000000000000000000020551376717241300320560ustar00rootroot00000000000000pragma Singleton import QtQml 2.2 import Colors 1.0 import Units 1.0 // ============================================================================= QtObject { property int leftMargin: 10 property QtObject attribute: QtObject { property int height: 40 property QtObject background: QtObject { property QtObject color: QtObject { property color normal: Colors.a property color hovered: Colors.o } } property QtObject dropArea: QtObject { property int margins: 5 } property QtObject text: QtObject { property color color: Colors.j property int pointSize: Units.dp * 10 } } property QtObject column: QtObject { property int bitrateWidth: 120 property int clockRateWidth: 100 property int encoderDescriptionWidth: 280 property int mimeWidth: 100 property int recvFmtpWidth: 200 property int spacing: 10 } property QtObject legend: QtObject { property color color: Colors.j property int pointSize: Units.dp * 10 property int height: 50 } } linphone-desktop-4.2.5/linphone-app/ui/modules/Linphone/Styles/Contact/000077500000000000000000000000001376717241300261315ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/ui/modules/Linphone/Styles/Contact/AvatarStyle.qml000066400000000000000000000005471376717241300311110ustar00rootroot00000000000000pragma Singleton import QtQml 2.2 import Colors 1.0 import Units 1.0 // ============================================================================= QtObject { property color backgroundColor: Colors.d property QtObject initials: QtObject { property color color: Colors.q property int pointSize: Units.dp * 10 property int ratio: 30 } } linphone-desktop-4.2.5/linphone-app/ui/modules/Linphone/Styles/Contact/ContactDescriptionStyle.qml000066400000000000000000000006351376717241300334700ustar00rootroot00000000000000pragma Singleton import QtQml 2.2 import Colors 1.0 import Units 1.0 // ============================================================================= QtObject { property QtObject sipAddress: QtObject { property color color: Colors.n property int pointSize: Units.dp * 10 } property QtObject username: QtObject { property color color: Colors.j property int pointSize: Units.dp * 11 } } ContactMessageCounterStyle.qml000066400000000000000000000003551376717241300340510ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/ui/modules/Linphone/Styles/Contactpragma Singleton import QtQml 2.2 import Colors 1.0 import Units 1.0 // ============================================================================= QtObject { property int horizontalMargins: 0 property int verticalMargins: 10 } linphone-desktop-4.2.5/linphone-app/ui/modules/Linphone/Styles/Contact/ContactStyle.qml000066400000000000000000000004251376717241300312610ustar00rootroot00000000000000pragma Singleton import QtQml 2.2 // ============================================================================= QtObject { property int contentHeight: 32 property int height: 50 property int leftMargin: 14 property int rightMargin: 14 property int spacing: 14 } linphone-desktop-4.2.5/linphone-app/ui/modules/Linphone/Styles/Dialog/000077500000000000000000000000001376717241300257355ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/ui/modules/Linphone/Styles/Dialog/OnlineInstallerDialogStyle.qml000066400000000000000000000014521376717241300337150ustar00rootroot00000000000000pragma Singleton import QtQml 2.2 import Colors 1.0 import Units 1.0 // ============================================================================= QtObject { property int height: 200 property int width: 400 property QtObject column: QtObject { property int spacing: 6 property QtObject bar: QtObject { property int height: 20 property int radius: 6 property QtObject background: QtObject { property color color: Colors.f } property QtObject contentItem: QtObject { property QtObject color: QtObject { property color failed: Colors.error property color normal: Colors.p } } } property QtObject text: QtObject { property color color: Colors.d property int pointSize: Units.dp * 11 } } } linphone-desktop-4.2.5/linphone-app/ui/modules/Linphone/Styles/History/000077500000000000000000000000001376717241300261775ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/ui/modules/Linphone/Styles/History/HistoryStyle.qml000066400000000000000000000026001376717241300313720ustar00rootroot00000000000000pragma Singleton import QtQml 2.2 import Colors 1.0 import Units 1.0 // ============================================================================= QtObject { property color color: Colors.q property QtObject sectionHeading: QtObject { property int padding: 5 property int bottomMargin: 20 property QtObject border: QtObject { property color color: Colors.g10 property int width: 1 } property QtObject text: QtObject { property int pointSize: Units.dp * 10 property color color: Colors.g } } property QtObject entry: QtObject { property int bottomMargin: 10 property int deleteIconSize: 22 property int leftMargin: 18 property int lineHeight: 30 property int metaWidth: 40 property QtObject event: QtObject { property int iconSize: 18 property QtObject text: QtObject { property color color: Colors.d property int pointSize: Units.dp * 10 } } property QtObject message: QtObject { property int padding: 8 property int radius: 4 property QtObject extraContent: QtObject { property int leftMargin: 10 property int spacing: 5 property int rightMargin: 5 } } property QtObject time: QtObject { property color color: Colors.d property int pointSize: Units.dp * 10 property int width: 44 } } } linphone-desktop-4.2.5/linphone-app/ui/modules/Linphone/Styles/Menus/000077500000000000000000000000001376717241300256255ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/ui/modules/Linphone/Styles/Menus/SipAddressesMenuStyle.qml000066400000000000000000000012431376717241300325770ustar00rootroot00000000000000pragma Singleton import QtQml 2.2 import Colors 1.0 import Units 1.0 // ============================================================================= QtObject { property int spacing: 1 property int maxHeight: 164 property QtObject entry: QtObject { property int leftMargin: 18 property int rightMargin: 8 property int height: 40 property int width: 300 property QtObject color: QtObject { property color hovered: Colors.j property color normal: Colors.g property color pressed: Colors.i } property QtObject text: QtObject { property color color: Colors.q property int pointSize: Units.dp * 10 } } } linphone-desktop-4.2.5/linphone-app/ui/modules/Linphone/Styles/Misc/000077500000000000000000000000001376717241300254315ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/ui/modules/Linphone/Styles/Misc/MessageCounterStyle.qml000066400000000000000000000006021376717241300321070ustar00rootroot00000000000000pragma Singleton import QtQml 2.2 import Colors 1.0 import Units 1.0 // ============================================================================= QtObject { property QtObject iconSize: QtObject { property int amount: 16 property int message: 18 } property QtObject text: QtObject { property color color: Colors.q property int pointSize: Units.dp * 7 } } linphone-desktop-4.2.5/linphone-app/ui/modules/Linphone/Styles/Notifications/000077500000000000000000000000001376717241300273475ustar00rootroot00000000000000NotificationBasicStyle.qml000066400000000000000000000005771376717241300344250ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/ui/modules/Linphone/Styles/Notificationspragma Singleton import QtQml 2.2 import Colors 1.0 import Units 1.0 // ============================================================================= QtObject { property int leftMargin: 30 property int rightMargin: 15 property int overrodeHeight: 55 property QtObject message: QtObject { property color color: Colors.h property int pointSize: Units.dp * 10 } } NotificationReceivedCallStyle.qml000066400000000000000000000005641376717241300357220ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/ui/modules/Linphone/Styles/Notificationspragma Singleton import QtQml 2.2 // ============================================================================= QtObject { property int spacing: 0 property int bottomMargin: 15 property int leftMargin: 15 property int rightMargin: 15 property QtObject actionArea: QtObject { property int iconSize: 40 property int rightButtonsGroupMargin: 15 } } NotificationReceivedFileMessageStyle.qml000066400000000000000000000011221376717241300372220ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/ui/modules/Linphone/Styles/Notificationspragma Singleton import QtQml 2.2 import Colors 1.0 import Units 1.0 // ============================================================================= QtObject { property color color: Colors.k property int leftMargin: 25 property int overrodeHeight: 55 property int rightMargin: 15 property int spacing: 10 property QtObject fileName: QtObject { property color color: Colors.h property int pointSize: Units.dp * 10 } property QtObject fileSize: QtObject { property color color: Colors.h property int pointSize: Units.dp * 9 property int width: 100 } } NotificationReceivedMessageStyle.qml000066400000000000000000000011571376717241300364320ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/ui/modules/Linphone/Styles/Notificationspragma Singleton import QtQml 2.2 import Colors 1.0 import Units 1.0 // ============================================================================= QtObject { property color color: Colors.k property int bottomMargin: 15 property int leftMargin: 15 property int overrodeHeight: 55 property int rightMargin: 15 property int spacing: 0 property QtObject messageContainer: QtObject { property color color: Colors.o property int radius: 6 property int margins: 10 property QtObject text: QtObject { property color color: Colors.l property int pointSize: Units.dp * 9 } } } linphone-desktop-4.2.5/linphone-app/ui/modules/Linphone/Styles/Notifications/NotificationStyle.qml000066400000000000000000000005601376717241300335320ustar00rootroot00000000000000pragma Singleton import QtQml 2.2 import Colors 1.0 // ============================================================================= QtObject { property color color: Colors.k property int height: 120 property int iconSize: 40 property int width: 300 property QtObject border: QtObject { property color color: Colors.n property int width: 1 } } linphone-desktop-4.2.5/linphone-app/ui/modules/Linphone/Styles/TelKeypad/000077500000000000000000000000001376717241300264205ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/ui/modules/Linphone/Styles/TelKeypad/TelKeypadStyle.qml000066400000000000000000000017041376717241300320400ustar00rootroot00000000000000pragma Singleton import QtQml 2.2 import Colors 1.0 import Units 1.0 // ============================================================================= QtObject { property int columnSpacing: 0 property int height: 180 property int rowSpacing: 0 property int width: 180 property color color: Colors.k property color selectedColor : Colors.m property int selectedBorderWidth: 2 property real radius : 5.0 property QtObject button: QtObject { property QtObject color: QtObject { property color normal: Colors.q property color pressed: Colors.i } property QtObject line: QtObject { property color color: Colors.l50 property int bottomMargin: 4 property int height: 2 property int leftMargin: 8 property int rightMargin: 8 property int topMargin: 0 } property QtObject text: QtObject { property color color: Colors.d property int pointSize: Units.dp * 11 } } } linphone-desktop-4.2.5/linphone-app/ui/modules/Linphone/Styles/Timeline/000077500000000000000000000000001376717241300263045ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/ui/modules/Linphone/Styles/Timeline/TimelineStyle.qml000066400000000000000000000022701376717241300316070ustar00rootroot00000000000000pragma Singleton import QtQml 2.2 import Colors 1.0 import Units 1.0 // ============================================================================= QtObject { property color color: Colors.q property QtObject contact: QtObject { property int height: 60 property QtObject backgroundColor: QtObject { property color a: Colors.g10 property color b: Colors.a property color selected: Colors.i } property QtObject sipAddress: QtObject { property QtObject color: QtObject { property color normal: Colors.n property color selected: Colors.q } } property QtObject username: QtObject { property QtObject color: QtObject { property color normal: Colors.j property color selected: Colors.q } } } property QtObject legend: QtObject { property QtObject backgroundColor: QtObject { property color normal: Colors.f property color hovered: Colors.c } property color color: Colors.d property int pointSize: Units.dp * 11 property int height: 30 property int iconSize: 14 property int leftMargin: 17 property int rightMargin: 17 property int spacing: 8 } } linphone-desktop-4.2.5/linphone-app/ui/modules/Linphone/Styles/View/000077500000000000000000000000001376717241300254505ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/ui/modules/Linphone/Styles/View/SipAddressesViewStyle.qml000066400000000000000000000023021376717241300324250ustar00rootroot00000000000000pragma Singleton import QtQml 2.2 import Colors 1.0 import Units 1.0 // ============================================================================= QtObject { property QtObject entry: QtObject { property int height: 50 property int iconSize: 36 property int rightMargin: 10 property QtObject color: QtObject { property color hovered: Colors.o property color normal: Colors.q } property QtObject indicator: QtObject { property color color: Colors.i property int width: 5 } property QtObject separator: QtObject { property color color: Colors.c property int height: 1 } } property QtObject header: QtObject { property int iconSize: 22 property int leftMargin: 20 property int rightMargin: 10 property QtObject button: QtObject { property int height: 40 } property QtObject color: QtObject { property color normal: Colors.j property color pressed: Colors.i } property QtObject text: QtObject { property int pointSize: Units.dp * 9 property QtObject color: QtObject { property color normal: Colors.q property color pressed: Colors.q } } } } linphone-desktop-4.2.5/linphone-app/ui/modules/Linphone/Styles/qmldir000066400000000000000000000043061376717241300257540ustar00rootroot00000000000000# See: https://wiki.qt.io/Qml_Styling module Linphone.Styles # Components styles ------------------------------------------------------------ singleton AccountStatusStyle 1.0 Account/AccountStatusStyle.qml singleton CardBlockStyle 1.0 Blocks/CardBlockStyle.qml singleton RequestBlockStyle 1.0 Blocks/RequestBlockStyle.qml singleton ChatStyle 1.0 Chat/ChatStyle.qml singleton CallControlsStyle 1.0 Calls/CallControlsStyle.qml singleton CallsStyle 1.0 Calls/CallsStyle.qml singleton CallStatisticsStyle 1.0 Calls/CallStatisticsStyle.qml singleton ConferenceControlsStyle 1.0 Calls/ConferenceControlsStyle.qml singleton CodecsViewerStyle 1.0 Codecs/CodecsViewerStyle.qml singleton AvatarStyle 1.0 Contact/AvatarStyle.qml singleton ContactDescriptionStyle 1.0 Contact/ContactDescriptionStyle.qml singleton ContactMessageCounterStyle 1.0 Contact/ContactMessageCounterStyle.qml singleton ContactStyle 1.0 Contact/ContactStyle.qml singleton OnlineInstallerDialogStyle 1.0 Dialog/OnlineInstallerDialogStyle.qml singleton HistoryStyle 1.0 History/HistoryStyle.qml singleton SipAddressesMenuStyle 1.0 Menus/SipAddressesMenuStyle.qml singleton MessageCounterStyle 1.0 Misc/MessageCounterStyle.qml singleton NotificationBasicStyle 1.0 Notifications/NotificationBasicStyle.qml singleton NotificationReceivedCallStyle 1.0 Notifications/NotificationReceivedCallStyle.qml singleton NotificationReceivedFileMessageStyle 1.0 Notifications/NotificationReceivedFileMessageStyle.qml singleton NotificationReceivedMessageStyle 1.0 Notifications/NotificationReceivedMessageStyle.qml singleton NotificationStyle 1.0 Notifications/NotificationStyle.qml singleton TelKeypadStyle 1.0 TelKeypad/TelKeypadStyle.qml singleton TimelineStyle 1.0 Timeline/TimelineStyle.qml singleton SipAddressesViewStyle 1.0 View/SipAddressesViewStyle.qml linphone-desktop-4.2.5/linphone-app/ui/modules/Linphone/TelKeypad/000077500000000000000000000000001376717241300251355ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/ui/modules/Linphone/TelKeypad/TelKeypad.js000066400000000000000000000036361376717241300273650ustar00rootroot00000000000000/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ // ============================================================================= // `TelKeypad.qml` Logic. // ============================================================================= .import Linphone.Styles 1.0 as LinphoneStyles .import 'qrc:/ui/scripts/Utils/utils.js' as Utils // ============================================================================= function mapKeyToButtonIndex (key) { // Digits. if (key === 48) { return 13 } if (key >= 49 && key <= 57) { return (key - 49) + parseInt((key - 49) / 3) } // A, B, C and D. if (key >= 65 && key <= 68) { return (key - 65) * 4 + 3 } // * if (key === 42) { return 12 } // # if (key === 35) { return 14 } } function sendDtmf (index) { var children = grid.children[index] children.color = LinphoneStyles.TelKeypadStyle.button.color.pressed children.clicked() var timeout = children._timeout if (timeout) { Utils.clearTimeout(timeout) } children._timeout = Utils.setTimeout(dragBox, 100, (function (index) { grid.children[index].color = LinphoneStyles.TelKeypadStyle.button.color.normal }).bind(dragBox, index)) } linphone-desktop-4.2.5/linphone-app/ui/modules/Linphone/TelKeypad/TelKeypad.qml000066400000000000000000000060651376717241300275410ustar00rootroot00000000000000import QtQuick 2.7 import QtQuick.Layouts 1.3 import Common 1.0 import Linphone.Styles 1.0 import 'TelKeypad.js' as Logic // ============================================================================= Rectangle { id: telKeypad property var container: parent property var call color: TelKeypadStyle.color // useless as it is overridden by buttons color, but keep it if buttons are transparent onActiveFocusChanged: {if(activeFocus) selectedArea.border.width=TelKeypadStyle.selectedBorderWidth; else selectedArea.border.width=0} layer { effect: PopupShadow {} enabled: true } height: TelKeypadStyle.height width: TelKeypadStyle.width radius:TelKeypadStyle.radius+1.0 // +1 for avoid mixing color with border slection (some pixels can be print after the line) Keys.onPressed: { var index = Logic.mapKeyToButtonIndex(event.key) if (index != null) { event.accepted = true Logic.sendDtmf(index) } } // --------------------------------------------------------------------------- GridLayout { id: grid anchors.fill: parent columns: 4 // Not a style. rows: 4 // Same idea. columnSpacing: TelKeypadStyle.columnSpacing rowSpacing: TelKeypadStyle.rowSpacing Repeater { model: [ '1', '2', '3', 'A', '4', '5', '6', 'B', '7', '8', '9', 'C', '*', '0', '#', 'D', ] TelKeypadButton { property var _timeout Layout.fillHeight: true Layout.fillWidth: true text: modelData onClicked: telKeypad.call.sendDtmf(modelData) } } } // --------------------------------------------------------------------------- DragBox { id: dragBox readonly property int delta: 5 property int _id property var _mouseX property var _mouseY container: telKeypad.container draggable: parent xPosition: (function () { return 80 }) yPosition: (function () { return 70 }) onPressed: { _mouseX = mouse.x _mouseY = mouse.y _id = parseInt(_mouseX / (parent.width / grid.columns)) + parseInt(_mouseY / (parent.height / grid.rows)) * grid.columns telKeypad.focus = true } onReleased: Math.abs(_mouseX - mouse.x) <= delta && Math.abs(_mouseY - mouse.y) <= delta && Logic.sendDtmf(_id) } Rectangle{ id: selectedArea anchors.fill:parent color:"transparent" border.color:TelKeypadStyle.selectedColor border.width:0 focus:false enabled:false radius:TelKeypadStyle.radius } MouseArea {// Just take hover events and set popup to do its automatic close if mouse is not inside field/popup area anchors.fill: parent onContainsMouseChanged: (containsMouse?telKeypad.forceActiveFocus():telKeypad.focus=false) hoverEnabled:true preventStealing: true propagateComposedEvents:true onPressed: mouse.accepted=false onReleased: mouse.accepted=false onClicked: mouse.accepted=false onDoubleClicked: mouse.accepted=false onPressAndHold: mouse.accepted=false } } linphone-desktop-4.2.5/linphone-app/ui/modules/Linphone/TelKeypad/TelKeypadButton.qml000066400000000000000000000025321376717241300307300ustar00rootroot00000000000000import QtQuick 2.7 import QtQuick.Layouts 1.3 import Linphone.Styles 1.0 // ============================================================================= Item { id: button property color color: TelKeypadStyle.button.color.normal property string text: '' signal clicked // --------------------------------------------------------------------------- Rectangle { anchors.fill: parent color: button.color radius:TelKeypadStyle.radius+2.0 ColumnLayout { anchors.fill: parent spacing: 0 Text { Layout.fillHeight: true Layout.fillWidth: true color: TelKeypadStyle.button.text.color elide: Text.ElideRight font { bold: true pointSize: TelKeypadStyle.button.text.pointSize } text: button.text horizontalAlignment: Text.AlignHCenter verticalAlignment: Text.AlignVCenter } Rectangle { Layout.fillWidth: true Layout.preferredHeight: TelKeypadStyle.button.line.height Layout.bottomMargin: TelKeypadStyle.button.line.bottomMargin Layout.leftMargin: TelKeypadStyle.button.line.leftMargin Layout.rightMargin: TelKeypadStyle.button.line.rightMargin Layout.topMargin: TelKeypadStyle.button.line.topMargin color: TelKeypadStyle.button.line.color } } } } linphone-desktop-4.2.5/linphone-app/ui/modules/Linphone/Timeline/000077500000000000000000000000001376717241300250215ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/ui/modules/Linphone/Timeline/Timeline.js000066400000000000000000000044441376717241300271330ustar00rootroot00000000000000/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ // ============================================================================= // `Timeline.qml` Logic. // ============================================================================= .import Linphone 1.0 as Linphone // ============================================================================= function setSelectedEntry (peerAddress, localAddress) { if (localAddress != null && localAddress !== Linphone.AccountSettingsModel.sipAddress) { resetSelectedEntry() return } var model = timeline.model var n = view.count timeline._selectedSipAddress = peerAddress for (var i = 0; i < n; i++) { if (peerAddress === model.data(model.index(i, 0)).sipAddress) { view.currentIndex = i return } } } function resetSelectedEntry () { view.currentIndex = -1 timeline._selectedSipAddress = '' } // ----------------------------------------------------------------------------- function handleDataChanged (topLeft, bottomRight, roles) { var index = view.currentIndex var model = timeline.model var sipAddress = timeline._selectedSipAddress if ( index !== -1 && sipAddress !== model.data(model.index(index, 0)).sipAddress ) { setSelectedEntry(sipAddress) } } function handleRowsAboutToBeRemoved (parent, first, last) { var index = view.currentIndex if (index >= first && index <= last) { view.currentIndex = -1 } } function handleCountChanged (_) { var sipAddress = timeline._selectedSipAddress if (sipAddress.length > 0) { setSelectedEntry(sipAddress) } } linphone-desktop-4.2.5/linphone-app/ui/modules/Linphone/Timeline/Timeline.qml000066400000000000000000000102461376717241300273050ustar00rootroot00000000000000import QtQuick 2.7 import QtQuick.Layouts 1.3 import Common 1.0 import Linphone 1.0 import Linphone.Styles 1.0 import 'Timeline.js' as Logic // ============================================================================= Rectangle { id: timeline // --------------------------------------------------------------------------- property alias model: view.model property string _selectedSipAddress // --------------------------------------------------------------------------- signal entrySelected (string entry) // --------------------------------------------------------------------------- function setSelectedEntry (peerAddress, localAddress) { Logic.setSelectedEntry(peerAddress, localAddress) } function resetSelectedEntry () { Logic.resetSelectedEntry() } // --------------------------------------------------------------------------- color: TimelineStyle.color ColumnLayout { anchors.fill: parent spacing: 0 // ------------------------------------------------------------------------- Connections { target: model onDataChanged: Logic.handleDataChanged(topLeft, bottomRight, roles) onRowsAboutToBeRemoved: Logic.handleRowsAboutToBeRemoved(parent, first, last) } // ------------------------------------------------------------------------- // Legend. // ------------------------------------------------------------------------- Rectangle { Layout.fillWidth: true Layout.preferredHeight: TimelineStyle.legend.height color: showHistory.containsMouse?TimelineStyle.legend.backgroundColor.hovered:TimelineStyle.legend.backgroundColor.normal MouseArea{ id:showHistory anchors.fill:parent onClicked: { view.currentIndex = -1 timeline.entrySelected('') } } Row { anchors { fill: parent leftMargin: TimelineStyle.legend.leftMargin rightMargin: TimelineStyle.legend.rightMargin } spacing: TimelineStyle.legend.spacing Icon { anchors.verticalCenter: parent.verticalCenter icon: 'timeline_history' iconSize: TimelineStyle.legend.iconSize } Text { color: TimelineStyle.legend.color font.pointSize: TimelineStyle.legend.pointSize height: parent.height text: qsTr('timelineTitle') verticalAlignment: Text.AlignVCenter } } } // ------------------------------------------------------------------------- // History. // ------------------------------------------------------------------------- ScrollableListView { id: view Layout.fillHeight: true Layout.fillWidth: true currentIndex: -1 delegate: Item { height: TimelineStyle.contact.height width: parent ? parent.width : 0 Contact { readonly property bool isSelected: view.currentIndex === index anchors.fill: parent color: isSelected ? TimelineStyle.contact.backgroundColor.selected : ( index % 2 == 0 ? TimelineStyle.contact.backgroundColor.a : TimelineStyle.contact.backgroundColor.b ) displayUnreadMessageCount: SettingsModel.chatEnabled entry: $timelineEntry sipAddressColor: isSelected ? TimelineStyle.contact.sipAddress.color.selected : TimelineStyle.contact.sipAddress.color.normal usernameColor: isSelected ? TimelineStyle.contact.username.color.selected : TimelineStyle.contact.username.color.normal Loader { anchors.fill: parent sourceComponent: TooltipArea { text: $timelineEntry.timestamp.toLocaleString( Qt.locale(App.locale), Locale.ShortFormat ) } } } MouseArea { anchors.fill: parent onClicked: { view.currentIndex = index timeline.entrySelected($timelineEntry.sipAddress) } } } onCountChanged: Logic.handleCountChanged(count) } } } linphone-desktop-4.2.5/linphone-app/ui/modules/Linphone/View/000077500000000000000000000000001376717241300241655ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/ui/modules/Linphone/View/SipAddressesView.qml000066400000000000000000000162421376717241300301310ustar00rootroot00000000000000import QtQuick 2.7 import QtQuick.Layouts 1.3 import Common 1.0 import Linphone 1.0 import Linphone.Styles 1.0 // ============================================================================= ScrollableListView { id: sipAddressesView // --------------------------------------------------------------------------- // Contains a list of: { // icon: 'string', // handler: function () { ... } // } property var actions: [] property string genSipAddress // Optional parameters. property string headerButtonDescription property string headerButtonIcon property var headerButtonAction readonly property string interpretableSipAddress: SipAddressesModel.interpretSipAddress( genSipAddress, false ) // --------------------------------------------------------------------------- signal entryClicked (var entry) // --------------------------------------------------------------------------- // Header. // --------------------------------------------------------------------------- header: MouseArea { height: { var height = headerButton.visible ? SipAddressesViewStyle.header.button.height : 0 if (defaultContact.visible) { height += SipAddressesViewStyle.entry.height } return height } width: parent.width // Workaround to handle mouse. // Without it, the mouse can be given to items list when mouse is hover header. hoverEnabled: true cursorShape: Qt.ArrowCursor Column { anchors.fill: parent spacing: 0 // ----------------------------------------------------------------------- // Default contact. // ----------------------------------------------------------------------- Loader { id: defaultContact height: SipAddressesViewStyle.entry.height width: parent.width visible: sipAddressesView.interpretableSipAddress.length > 0 sourceComponent: Rectangle { anchors.fill: parent color: SipAddressesViewStyle.entry.color.normal RowLayout { anchors { fill: parent rightMargin: SipAddressesViewStyle.entry.rightMargin } spacing: 0 Contact { id: contact Layout.fillHeight: true Layout.fillWidth: true entry: ({ sipAddress: sipAddressesView.interpretableSipAddress }) } ActionBar { id: defaultContactActionBar iconSize: SipAddressesViewStyle.entry.iconSize Repeater { model: sipAddressesView.actions ActionButton { icon: modelData.icon visible: { var visible = sipAddressesView.actions[index].visible return visible === undefined || visible } onClicked: sipAddressesView.actions[index].handler({ sipAddress: sipAddressesView.interpretableSipAddress }) } } } } } } // ----------------------------------------------------------------------- // Header button. // ----------------------------------------------------------------------- MouseArea { id: headerButton height: SipAddressesViewStyle.header.button.height width: parent.width visible: !!sipAddressesView.headerButtonAction onClicked: sipAddressesView.headerButtonAction(sipAddressesView.interpretableSipAddress) Rectangle { anchors.fill: parent color: parent.pressed ? SipAddressesViewStyle.header.color.pressed : SipAddressesViewStyle.header.color.normal Text { anchors { left: parent.left leftMargin: SipAddressesViewStyle.header.leftMargin verticalCenter: parent.verticalCenter } font { bold: true pointSize: SipAddressesViewStyle.header.text.pointSize } color: headerButton.pressed ? SipAddressesViewStyle.header.text.color.pressed : SipAddressesViewStyle.header.text.color.normal text: sipAddressesView.headerButtonDescription } Icon { anchors { right: parent.right rightMargin: SipAddressesViewStyle.header.rightMargin verticalCenter: parent.verticalCenter } icon: sipAddressesView.headerButtonIcon iconSize: SipAddressesViewStyle.header.iconSize visible: icon.length > 0 } } } } } // --------------------------------------------------------------------------- // Entries. // --------------------------------------------------------------------------- delegate: Rectangle { id: sipAddressEntry color: SipAddressesViewStyle.entry.color.normal height: SipAddressesViewStyle.entry.height width: parent ? parent.width : 0 Rectangle { id: indicator anchors.left: parent.left color: 'transparent' height: parent.height width: SipAddressesViewStyle.entry.indicator.width } MouseArea { id: mouseArea anchors.fill: parent cursorShape: Qt.ArrowCursor RowLayout { anchors { fill: parent rightMargin: SipAddressesViewStyle.entry.rightMargin } spacing: 0 // --------------------------------------------------------------------- // Contact or address info. // --------------------------------------------------------------------- Contact { Layout.fillHeight: true Layout.fillWidth: true entry: $sipAddress MouseArea { anchors.fill: parent onClicked: sipAddressesView.entryClicked($sipAddress) } } // --------------------------------------------------------------------- // Actions // --------------------------------------------------------------------- ActionBar { iconSize: SipAddressesViewStyle.entry.iconSize Repeater { model: sipAddressesView.actions ActionButton { icon: modelData.icon visible: { var visible = sipAddressesView.actions[index].visible return visible === undefined || visible } onClicked: sipAddressesView.actions[index].handler($sipAddress) } } } } } // Separator. Rectangle { color: SipAddressesViewStyle.entry.separator.color height: SipAddressesViewStyle.entry.separator.height width: parent.width } // ------------------------------------------------------------------------- states: State { when: mouseArea.containsMouse PropertyChanges { color: SipAddressesViewStyle.entry.color.hovered target: sipAddressEntry } PropertyChanges { color: SipAddressesViewStyle.entry.indicator.color target: indicator } } } } linphone-desktop-4.2.5/linphone-app/ui/modules/Linphone/qmldir000066400000000000000000000022161376717241300244670ustar00rootroot00000000000000# ============================================================================== # Linphone's components to export. # ============================================================================== module Linphone # Components ------------------------------------------------------------------- AccountStatus 1.0 Account/AccountStatus.qml CardBlock 1.0 Blocks/CardBlock.qml RequestBlock 1.0 Blocks/RequestBlock.qml Calls 1.0 Calls/Calls.qml CallStatistics 1.0 Calls/CallStatistics.qml Chat 1.0 Chat/Chat.qml History 1.0 History/History.qml CodecsViewer 1.0 Codecs/CodecsViewer.qml Avatar 1.0 Contact/Avatar.qml Contact 1.0 Contact/Contact.qml ContactDescription 1.0 Contact/ContactDescription.qml SipAddressesMenu 1.0 Menus/SipAddressesMenu.qml MessageCounter 1.0 Misc/MessageCounter.qml PresenceLevel 1.0 Presence/PresenceLevel.qml SmartSearchBar 1.0 SmartSearchBar/SmartSearchBar.qml TelKeypad 1.0 TelKeypad/TelKeypad.qml Timeline 1.0 Timeline/Timeline.qml SipAddressesView 1.0 View/SipAddressesView.qml linphone-desktop-4.2.5/linphone-app/ui/scripts/000077500000000000000000000000001376717241300215165ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/ui/scripts/LinphoneUtils/000077500000000000000000000000001376717241300243135ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/ui/scripts/LinphoneUtils/linphone-utils.js000066400000000000000000000106551376717241300276320ustar00rootroot00000000000000/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ // ============================================================================= // Contains linphone helpers. // ============================================================================= .pragma library .import Linphone 1.0 as Linphone .import 'qrc:/ui/scripts/Utils/utils.js' as Utils // ============================================================================= // Contact/SIP address helpers. // ============================================================================= function _getDisplayNameFromQuotedString (str) { var start = str.indexOf('"') if (start === -1) { return } var end = str.lastIndexOf('"') if (end === -1 || start === end) { return } return str.substring(start + 1, end) } function _getDisplayNameFromString (str) { var end = str.indexOf('<') if (end === -1) { return } return str.substring(0, end).trim() || undefined } function _getDisplayName (str) { var name = _getDisplayNameFromQuotedString(str) if (name != null) { return name } return _getDisplayNameFromString(str) } // ----------------------------------------------------------------------------- function _getUsername (str) { var start = str.indexOf('sip') if (start === -1) { return } start += 4 + Number(str.charAt(start + 4) === ':') // Deal with `sip:` and `sips:` var end = str.indexOf('@', start + 1) if (end === -1) { return Utils.decode(str.substring(start)) } return Utils.decode(str.substring(start, end)) } // ----------------------------------------------------------------------------- // Returns the username of a contact/sipAddressObserver object or URI string. function getContactUsername (contact) { if(contact){ var object = contact.contact || // Contact object from `SipAddressObserver`. (contact.vcard && contact) // Contact object. // 1. `object` is a contact. if (object) { return object.vcard.username } // 2. `object` is just a string. object = Utils.isString(contact.peerAddress) ? contact.peerAddress // String from `SipAddressObserver`. : contact // Just a String. // Use display name. var name = _getDisplayName(object) if (name != null) { return name } // Use username. name = _getUsername(object) return name == null ? 'Bad EGG' : name }else return ''; } // ============================================================================= // Codec helpers. // ============================================================================= function openCodecOnlineInstallerDialog (window, codecInfo, cb) { var VideoCodecsModel = Linphone.VideoCodecsModel window.attachVirtualWindow(Utils.buildDialogUri('ConfirmDialog'), { descriptionText: qsTr('downloadCodecDescription') .replace('%1', codecInfo.mime) .replace('%2', codecInfo.encoderDescription) }, function (status) { if (status) { window.attachVirtualWindow(buildDialogUri('OnlineInstallerDialog'), { downloadUrl: codecInfo.downloadUrl, extract: true, installFolder: VideoCodecsModel.codecsFolder, installName: codecInfo.installName, mime: codecInfo.mime }, function (status) { if (status) { VideoCodecsModel.reload() } if (cb) { cb(window) } }) } else if (cb) { cb(window) } }) } // ============================================================================= // QML helpers. // ============================================================================= function buildDialogUri (component) { return 'qrc:/ui/modules/Linphone/Dialog/' + component + '.qml' } linphone-desktop-4.2.5/linphone-app/ui/scripts/LinphoneUtils/qmldir000066400000000000000000000000721376717241300255250ustar00rootroot00000000000000module LinphoneUtils LinphoneUtils 1.0 linphone-utils.js linphone-desktop-4.2.5/linphone-app/ui/scripts/Utils/000077500000000000000000000000001376717241300226165ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/ui/scripts/Utils/port-tools.js000066400000000000000000000026051376717241300253010ustar00rootroot00000000000000/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ // ============================================================================= // Library to deal with Ports. // ============================================================================= .pragma library // ----------------------------------------------------------------------------- var PORT = '([0-9]{1,4}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])' var PORT_RANGE = PORT + '(?::' + PORT + ')?' // ----------------------------------------------------------------------------- var PORT_REGEX = new RegExp('^' + PORT + '$') var PORT_RANGE_REGEX = new RegExp('^' + PORT_RANGE + '$') linphone-desktop-4.2.5/linphone-app/ui/scripts/Utils/qmldir000066400000000000000000000000411376717241300240240ustar00rootroot00000000000000module Utils Utils 1.0 utils.js linphone-desktop-4.2.5/linphone-app/ui/scripts/Utils/uri-tools.js000066400000000000000000000112531376717241300251130ustar00rootroot00000000000000/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ // ============================================================================= // Library to deal with URI. // See: https://tools.ietf.org/html/rfc3986#section-1.3 // ============================================================================= .pragma library // Options. // If true, strings starting with `www.` can be detected. // Not standard but helpful. var SUPPORTS_URL = true // Level 0. -------------------------------------------------------------------- var URI_DEC_OCTET = '(?:' + '25[0-5]' + '|' + '2[0-4]\\d' + '|' + '1\\d{2}' + '|' + '[1-9]\\d' + '|' + '\\d' + ')' var URI_H16 = '[0-9A-Fa-f]{1,4}' var URI_PCT_ENCODED = '%[A-Fa-f\\d]{2}' var URI_PORT = '\\d*' var URI_SCHEME = '[a-zA-Z][\\w+\-\.]*' var URI_SUB_DELIMS = '[!$&\'()*+,;=]' var URI_UNRESERVED = '[\\w\-\._~]' // Level 1. -------------------------------------------------------------------- var URI_IPV_FUTURE = 'v[0-9A-Fa-f]+\\.' + '(?:' + URI_UNRESERVED + URI_SUB_DELIMS + ':' + ')' var URI_IPV4_ADDRESS = URI_DEC_OCTET + '\\.' + URI_DEC_OCTET + '\\.' + URI_DEC_OCTET + '\\.' + URI_DEC_OCTET var URI_PCHAR = '(?:' + URI_UNRESERVED + '|' + URI_PCT_ENCODED + '|' + URI_SUB_DELIMS + '|' + '[:@]' + ')' var URI_REG_NAME = '(?:' + URI_UNRESERVED + '|' + URI_PCT_ENCODED + '|' + URI_SUB_DELIMS + ')*' var URI_USERINFO = '(?:' + URI_UNRESERVED + '|' + URI_PCT_ENCODED + '|' + URI_SUB_DELIMS + '|' + ':' + ')*' // Level 2. -------------------------------------------------------------------- var URI_FRAGMENT = '(?:' + URI_PCHAR + '|' + '[/?]' + ')*' var URI_LS32 = '(?:' + URI_H16 + ':' + URI_H16 + '|' + URI_IPV4_ADDRESS + ')' var URI_QUERY = '(?:' + URI_PCHAR + '|' + '[/?]' + ')*' var URI_SEGMENT = URI_PCHAR + '*' var URI_SEGMENT_NZ = URI_PCHAR + '+' // Level 3. -------------------------------------------------------------------- var URI_IPV6_ADDRESS = '(?:' + '(?:' + URI_H16 + ':){6}' + URI_LS32 + '|' + '::(?:' + URI_H16 + ':){5}' + URI_LS32 + '|' + '\\[' + URI_H16 + '\\]::(?:' + URI_H16 + ':){4}' + URI_LS32 + '|' + '\\[' + '(?:' + URI_H16 + ':)?' + URI_H16 + '\\]::(?:' + URI_H16 + ':){3}' + URI_LS32 + '|' + '\\[' + '(?:' + URI_H16 + ':){0,2}' + URI_H16 + '\\]::(?:' + URI_H16 + ':){2}' + URI_LS32 + '|' + '\\[' + '(?:' + URI_H16 + ':){0,3}' + URI_H16 + '\\]::' + URI_H16 + ':' + URI_LS32 + '|' + '\\[' + '(?:' + URI_H16 + ':){0,4}' + URI_H16 + '\\]::' + URI_LS32 + '|' + '\\[' + '(?:' + URI_H16 + ':){0,5}' + URI_H16 + '\\]::' + URI_H16 + '|' + '\\[' + '(?:' + URI_H16 + ':){0,6}' + URI_H16 + '\\]::' + ')' var URI_PATH_ABEMPTY = '(?:' + '/' + URI_SEGMENT + ')*' var URI_PATH_ABSOLUTE = '/' + '(?:' + URI_SEGMENT_NZ + '(?:' + '/' + URI_SEGMENT + ')*' + ')?' var URI_PATH_ROOTLESS = URI_SEGMENT_NZ + '(?:' + '/' + URI_SEGMENT + ')*' // Level 4. -------------------------------------------------------------------- var URI_IP_LITERAL = '\\[' + '(?:' + URI_IPV6_ADDRESS + '|' + URI_IPV_FUTURE + ')' + '\\]' // Level 5. -------------------------------------------------------------------- var URI_HOST = '(?:' + URI_REG_NAME + '|' + URI_IPV4_ADDRESS + '|' + URI_IP_LITERAL + ')' // Level 6. -------------------------------------------------------------------- var URI_AUTHORITY = '(?:' + URI_USERINFO + '@' + ')?' + URI_HOST + '(?:' + ':' + URI_PORT + ')?' // Level 7. -------------------------------------------------------------------- // `path-empty` not used. var URI_HIER_PART = '(?:' + '//' + URI_AUTHORITY + URI_PATH_ABEMPTY + '|' + URI_PATH_ABSOLUTE + '|' + URI_PATH_ROOTLESS + ')' // Level 8. -------------------------------------------------------------------- // Regex to match URI. It respects the RFC 3986. var URI = (SUPPORTS_URL ? '(?:' + URI_SCHEME + ':' + '|' + 'www\\.' + ')' : URI_SCHEME + ':' ) + URI_HIER_PART + '(?:' + '\\?' + URI_QUERY + ')?' + '(?:' + '#' + URI_FRAGMENT + ')?' var URI_REGEX = new RegExp('(' + URI + ')', 'g') linphone-desktop-4.2.5/linphone-app/ui/scripts/Utils/uri-tools.spec.qml000066400000000000000000000120301376717241300262130ustar00rootroot00000000000000import QtTest 1.1 import 'uri-tools.js' as UriTools // ============================================================================= TestCase { function test_regexExists () { compare( UriTools.URI_REGEX instanceof RegExp, true, '`URI_REGEX` is not a `RegExp` or is undefined.' ) } function test_urlSupport () { compare( typeof UriTools.SUPPORTS_URL, 'boolean', '`SUPPORTS_URL` is not a `Boolean` or is undefined.' ) } function test_matchUri_data () { return [ // ======================================================================= // Must match. // ======================================================================= { input: 'http://www.LaRmInA.com/', output: [ 'http://www.LaRmInA.com/' ] }, { input: 'http://foob%3Dbar@baz.fr', output: [ 'http://foob%3Dbar@baz.fr' ] }, { input: 'file://a/b/c/;d', output: [ 'file://a/b/c/;d' ] }, { input: 'ftp://0/', output: [ 'ftp://0/' ] }, { input: 'mailto://valentin.cognito@domain.unknown', output: [ 'mailto://valentin.cognito@domain.unknown' ] }, { input: 'mailto://sLimAne@egypt', output: [ 'mailto://sLimAne@egypt' ] }, { input: 'file://beetlejuice-beetlejuice-beetlejui...', output: [ 'file://beetlejuice-beetlejuice-beetlejui...' ] }, { input: 'https://gitlab@localhost', output: [ 'https://gitlab@localhost' ] }, { input: 'xmpp:von.zimmel@reich.org', output: [ 'xmpp:von.zimmel@reich.org' ] }, { input: 'dot.dot://dot.dot.dot@dot.dot.dot', output: [ 'dot.dot://dot.dot.dot@dot.dot.dot' ] }, { input: 'A:B', output: [ 'A:B' ] }, { input: 'foo://a=B.7z*+9aZb;$.!,!,!_(~_~)_-&\':', output: [ 'foo://a=B.7z*+9aZb;$.!,!,!_(~_~)_-&\':' ] }, { input: 'foo+bar+baz://hey:1800/it-s-me?a&b=12', output: [ 'foo+bar+baz://hey:1800/it-s-me?a&b=12' ] }, { input: 'nsa://localhost:666', output: [ 'nsa://localhost:666' ] }, { input: 'protocol://U$3r:p@sswd/WwW.L33t.sp3', output: [ 'protocol://U$3r:p@sswd/WwW.L33t.sp3' ] }, { input: 'foo://username:password@www.example.com:123/hello/world/there.html?name=ferret#foo', output: [ 'foo://username:password@www.example.com:123/hello/world/there.html?name=ferret#foo' ] }, { input: 'lalala://lololo.titi/tata_(tutu)#riri-0', output: [ 'lalala://lololo.titi/tata_(tutu)#riri-0' ] }, { input: 'dest://007@uk.en:8080/', output: [ 'dest://007@uk.en:8080/' ] }, { input: 'fefe://zef.sfdfzfds.vfs/zrefz/?vsfezzef=afzfefg&zfefezfze=7275&grgr', output: [ 'fefe://zef.sfdfzfds.vfs/zrefz/?vsfezzef=afzfefg&zfefezfze=7275&grgr' ] }, { input: 'fefe://xcv.zefe/(fzfff)?zefezef=fzefzef', output: [ 'fefe://xcv.zefe/(fzfff)?zefezef=fzefzef' ] }, { input: 'feeffsd://vccvx.zzef.dfs/xcvvcx/#&zfe=zfe', output: [ 'feeffsd://vccvx.zzef.dfs/xcvvcx/#&zfe=zfe' ] }, { input: 'http://256.1.1.1', output: [ 'http://256.1.1.1' ] // Valid URI. Invalid URL. }, { input: 'http://0.0.0.0', output: [ 'http://0.0.0.0' ] // Same idea. }, { input: 'http://a.b--c.de/', output: [ 'http://a.b--c.de/' ] // And again. }, { input: 'http://1.0.1.0.1.0', output: [ 'http://1.0.1.0.1.0' ] // AND AGAIN. }, { input: 'http://abc.c.d.', output: [ 'http://abc.c.d.' ] // AAAAND AAAGAAAIIIIIN. }, { input: 'https://a.b-c.de/', output: [ 'https://a.b-c.de/' ] }, { input: 'http://a/B/c?a&b&c', output: [ 'http://a/B/c?a&b&c' ] }, { input: '1http://www.linphone.org', output: [ 'http://www.linphone.org' ] }, { input: 'http://255.254.255.254', output: [ 'http://255.254.255.254' ] }, { input: 'http://12.42.1.10/', output: [ 'http://12.42.1.10/' ] }, // ======================================================================= // Partial or no match. // ======================================================================= { input: '://www.linphone.org', output: UriTools.SUPPORTS_URL ? [ 'www.linphone.org' ] : null }, { input: 'http', output: null }, { input: '/path/', output: null }, { input: 'http://✪dragooooonnnn✪ball✪z✪z✪z.goku/4', output: [ 'http://' ] }, { input: 'http:// iamafail.fr', output: [ 'http://' ] }, { input: 'isaac://石村.jp', output: [ 'isaac://' ] }, { input: ':// not good', output: null }, { input: 'http://☺.☺.☺', output: [ 'http://' ] } ] } function test_matchUri (data) { compare(data.input.match(UriTools.URI_REGEX), data.output) } } linphone-desktop-4.2.5/linphone-app/ui/scripts/Utils/utils.js000066400000000000000000000414611376717241300243220ustar00rootroot00000000000000/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ // ============================================================================= // Contains many common helpers. // ============================================================================= .pragma library .import QtQuick 2.7 as QtQuick .import 'port-tools.js' as PortTools .import 'uri-tools.js' as UriTools // ============================================================================= // Constants. // ============================================================================= var PORT_REGEX = PortTools.PORT_REGEX var PORT_RANGE_REGEX = PortTools.PORT_RANGE_REGEX var SCHEME_REGEX = new RegExp('^[^:]+:') // ============================================================================= // QML helpers. // ============================================================================= function buildDialogUri (component) { return 'qrc:/ui/modules/Common/Dialog/' + component + '.qml' } // ----------------------------------------------------------------------------- // Destroy timeout. function clearTimeout (timer) { timer.stop() // NECESSARY. timer.destroy() } // ----------------------------------------------------------------------------- function createObject (source, parent, options) { if (options && options.isString) { var object = Qt.createQmlObject(source, parent) var properties = options && options.properties if (properties) { for (var key in properties) { object[key] = properties[key] } } return object } var component = Qt.createComponent(source) if (component.status !== QtQuick.Component.Ready) { console.debug('Component not ready.') if (component.status === QtQuick.Component.Error) { console.debug('Error: ' + component.errorString()) } return // Error. } var object = component.createObject(parent, (options && options.properties) || {}) if (!object) { console.debug('Error: unable to create dynamic object.') } return object } // ----------------------------------------------------------------------------- function encodeTextToQmlRichFormat (text, options) { var images = '' if (!options) { options = {} } var formattedText = execAll(UriTools.URI_REGEX, text, function (str, valid) { if (!valid) { return unscapeHtml(str) } var uri = startsWith(str, 'www.') ? 'http://' + str : str var ext = getExtension(str) if (includes([ 'jpg', 'jpeg', 'gif', 'png', 'svg' ], ext)) { images += '' } return '' + unscapeHtml(str) + '' }).join('') if (images.length > 0) { images = '
' + images + '
' } return images.concat('

' + formattedText + '

') } function extractFirstUri (str) { var res = str.match(UriTools.URI_REGEX) return res == null || startsWith(res[0], 'www') ? undefined : res[0] } // ----------------------------------------------------------------------------- function getSystemPathFromUri (uri) { var str = uri.toString() if (startsWith(str, 'file://')) { str = str.substring(7) // Absolute path. if (str.charAt(0) === '/') { return runOnWindows() ? str.substring(1) : str } } return str } function getUriFromSystemPath (path) { if (path.startsWith('file://')) { return path } if (runOnWindows()) { return 'file://' + (/^\w:/.exec(path) ? '/' : '') + path } return 'file://' + path } // ----------------------------------------------------------------------------- // Returns the top (root) parent of one object. function getTopParent (object, useFakeParent) { function _getTopParent (object, useFakeParent) { return (useFakeParent && object.$parent) || object.parent } var parent = _getTopParent(object, useFakeParent) var p while ((p = _getTopParent(parent, useFakeParent)) != null) { parent = p } return parent } // ----------------------------------------------------------------------------- // Load by default a window in the ui/views folder. // If options.isString is equals to true, a marshalling component can // be used. // // Supported options: isString, exitHandler, properties. // // If exitHandler is used, window must implement exitStatus signal. function openWindow (window, parent, options, fullscreen) { var object = createObject(window, parent, options) object.closing.connect(object.destroy.bind(object)) if (options && options.exitHandler) { object.exitStatus.connect( // Bind to access parent properties. options.exitHandler.bind(parent) ) } if( runOnWindows()){ object.show() // Needed for Windows : Show the window in all case. Allow to graphically locate the window before going to fullscreen. if(fullscreen) object.showFullScreen()// Should be equivalent to changing visibility }else if(fullscreen) object.showFullScreen()// Should be equivalent to changing visibility else object.show() return object } // ----------------------------------------------------------------------------- function resolveImageUri (name) { return name ? 'image://internal/' + removeScheme(Qt.resolvedUrl('/assets/images/' + name + '.svg')) : '' } // ----------------------------------------------------------------------------- function runOnWindows () { var os = Qt.platform.os return os === 'windows' || os === 'winrt' } // ----------------------------------------------------------------------------- // Test if a point is in a item. // // `source` is the item that generated the point. // `target` is the item to test. // `point` is the point to test. function pointIsInItem (source, target, point) { point = source.mapToItem(target.parent, point.x, point.y) return ( point.x >= target.x && point.y >= target.y && point.x < target.x + target.width && point.y < target.y + target.height ) } // ----------------------------------------------------------------------------- // Test the type of a qml object. // Warning: this function is probably not portable // on new versions of Qt. // // So, if you want to use it on a specific `className`, please to add // a test in `test_qmlTypeof_data` of `utils.spec.qml`. function qmlTypeof (object, className) { var str = object.toString() return ( str.indexOf(className + '(') == 0 || str.indexOf(className + '_QML') == 0 ) } // ----------------------------------------------------------------------------- function removeScheme (url) { return url.toString().replace(SCHEME_REGEX, '') } // ----------------------------------------------------------------------------- // A copy of `Window.setTimeout` from js. // delay is in milliseconds. function setTimeout (parent, delay, cb) { var timer = new (function (parent) { return Qt.createQmlObject('import QtQml 2.2; Timer { }', parent) })(parent) timer.interval = delay timer.repeat = false timer.triggered.connect(cb) timer.start() return timer } // ============================================================================= // GENERIC. // ============================================================================= function _computeOptimizedCb (func, context) { return context ? (function () { return func.apply(context, arguments) }) : func } function _indexFinder (array, cb, context) { var length = array.length for (var i = 0; i < length; i++) { if (cb(array[i], i, array)) { return i } } return -1 } function _keyFinder (obj, cb, context) { var keys = Object.keys(obj) var length = keys.length for (var i = 0; i < length; i++) { var key = keys[i] if (cb(obj[key], key, obj)) { return key } } } // ----------------------------------------------------------------------------- // Basic assert function. function assert (condition, message) { if (!condition) { throw new Error('Assert: ' + message) } } // ----------------------------------------------------------------------------- function basename (str) { if (!str) { return '' } if (runOnWindows()) { str = str.replace(/\\/g, '/') } var str2 = str var length = str2.length - 1 if (str2[length] === '/') { str2 = str2.substring(0, length) } return str2.slice(str2.lastIndexOf('/') + 1) } // ----------------------------------------------------------------------------- function capitalizeFirstLetter (str) { return str.charAt(0).toUpperCase() + str.slice(1) } // ----------------------------------------------------------------------------- function dirname (str) { if (!str) { return '' } if (runOnWindows()) { str = str.replace(/\\/g, '/') } var str2 = str var length = str2.length - 1 if (str2[length] === '/') { str2 = str2.substring(0, length) } return str2.slice(0, str2.lastIndexOf('/') + 1) } // ----------------------------------------------------------------------------- function execAll (regex, text, cb) { var index = 0 var arr = [] var match if (!cb) { cb = function (text) { return text } } while ((match = regex.exec(text))) { var curIndex = match.index var matchStr = match[0] if (curIndex > index) { arr.push(cb(text.substring(index, curIndex), false)) } arr.push(cb(matchStr, true)) index = curIndex + matchStr.length } var length = text.length if (index < length) { arr.push(cb(text.substring(index, length))) } return arr } // ----------------------------------------------------------------------------- function extractProperties (obj, pattern) { if (!pattern) { return {} } var obj2 = {} pattern.forEach(function (property) { obj2[property] = obj[property] }) return obj2 } // ----------------------------------------------------------------------------- // Returns an array from an `object` or `array` argument. function ensureArray (obj) { if (isArray(obj)) { return obj } var keys = Object.keys(obj) var length = keys.length var values = Array(length) for (var i = 0; i < length; i++) { values[i] = obj[keys[i]] } return values } // ----------------------------------------------------------------------------- function escapeQuotes (str) { return str != null ? str.replace(/([^'\\]*(?:\\.[^'\\]*)*)'/g, '$1\\\'') : '' } function decode(str){ return decodeURIComponent(escape(str.replace(/%([0-9A-Fa-f]{2})/g, function() { return String.fromCharCode(parseInt(arguments[1], 16)); }))); } // ----------------------------------------------------------------------------- // Get the first matching value in a array or object. // The matching value is obtained if `cb` returns true. function find (obj, cb, context) { cb = _computeOptimizedCb(cb, context) var finder = isArray(obj) ? _indexFinder : _keyFinder var key = finder(obj, cb, context) return key != null && key !== -1 ? obj[key] : null } // ----------------------------------------------------------------------------- function findIndex (array, cb, context) { cb = _computeOptimizedCb(cb, context) var key = _indexFinder(array, cb, context) return key != null ? key : -1 } // ----------------------------------------------------------------------------- function formatElapsedTime (seconds) { seconds = parseInt(seconds, 10) var h = Math.floor(seconds / 3600) var m = Math.floor((seconds - h * 3600) / 60) var s = seconds - h * 3600 - m * 60 if (h < 10 && h > 0) { h = '0' + h } if (m < 10) { m = '0' + m } if (s < 10) { s = '0' + s } return (h === 0 ? '' : h + ':') + m + ':' + s } // ----------------------------------------------------------------------------- function formatSize (size) { var units = ['KB', 'MB', 'GB', 'TB'] var unit = 'B' if (size == null) { size = 0 } var length = units.length for (var i = 0; size >= 1024 && i < length; i++) { unit = units[i] size /= 1024 } return parseFloat(size.toFixed(2)) + unit } // ----------------------------------------------------------------------------- // Generate a random number in the [min, max[ interval. // Uniform distrib. function genRandomNumber (min, max) { return Math.random() * (max - min) + min } // ----------------------------------------------------------------------------- // Generate a random number between a set of intervals. // The `intervals` param must be orderer like this: // `[ [ 1, 4 ], [ 8, 16 ], [ 22, 25 ] ]` function genRandomNumberBetweenIntervals (intervals) { if (intervals.length === 1) { return genRandomNumber(intervals[0][0], intervals[0][1]) } // Compute the intervals size. var size = 0 intervals.forEach(function (interval) { size += interval[1] - interval[0] }) // Generate a value in the interval: `[0, size[` var n = genRandomNumber(0, size) // Map the value in the right interval. n += intervals[0][0] for (var i = 0; i < intervals.length - 1; i++) { if (n < intervals[i][1]) { break } n += intervals[i + 1][0] - intervals[i][1] } return n } // ----------------------------------------------------------------------------- // Returns the extension of a filename. function getExtension (str) { var index = str.lastIndexOf('.') if (index === -1) { return '' } return str.slice(index + 1) } // ----------------------------------------------------------------------------- // Test if a value is included in an array or object. function includes (obj, value, startIndex) { obj = ensureArray(obj) if (startIndex == null) { startIndex = 0 } var length = obj.length for (var i = startIndex; i < length; i++) { if ( value === obj[i] || // Check `NaN`. (value !== value && obj[i] !== obj[i]) ) { return true } } return false } // ----------------------------------------------------------------------------- function isArray (array) { return (array instanceof Array) } // ----------------------------------------------------------------------------- function isFunction (func) { return typeof func === 'function' } // ----------------------------------------------------------------------------- function isInteger (integer) { return integer === parseInt(integer, 10) } // ----------------------------------------------------------------------------- function isObject (object) { return object !== null && typeof object === 'object' } // ----------------------------------------------------------------------------- function isString (string) { return typeof string === 'string' || string instanceof String } // ----------------------------------------------------------------------------- // Convert a snake_case string to a lowerCamelCase string. function snakeToCamel (s) { return s.replace(/(\_\w)/g, function (matches) { return matches[1].toUpperCase() }) } // ----------------------------------------------------------------------------- // Test if a string starts by a given string. function startsWith (str, searchStr) { if (searchStr == null) { searchStr = '' } return str.slice(0, searchStr.length) === searchStr } // ----------------------------------------------------------------------------- // Invoke a `cb` function with each value of the interval: `[0, n[`. // Return a mapped array created with the returned values of `cb`. function times (n, cb, context) { var arr = Array(Math.max(0, n)) cb = _computeOptimizedCb(cb, context, 1) for (var i = 0; i < n; i++) { arr[i] = cb(i) } return arr } // ----------------------------------------------------------------------------- function unscapeHtml (str) { return str.replace(/&/g, '&') .replace(//g, '\u2063>') .replace(/"/g, '"') .replace(/'/g, ''') } // ----------------------------------------------------------------------------- function write (fileName, text) { // TODO: Deal with async. var request = new XMLHttpRequest() request.open('PUT', getUriFromSystemPath(fileName), false) request.send(text) } linphone-desktop-4.2.5/linphone-app/ui/scripts/Utils/utils.spec.qml000066400000000000000000000261501376717241300254260ustar00rootroot00000000000000import QtQuick 2.7 import QtTest 1.1 // Explicit import, `utils.js` is not accessible in resources file // when tests are executed. import './utils.js' as Utils // ============================================================================= TestCase { id: testCase // =========================================================================== // QML helpers. // =========================================================================== function test_clearTimeout_data () { return [ { time: 0 }, { time: 100 } ] } function test_clearTimeout (data) { var failed = false var timeout = Utils.setTimeout(testCase, data.time, function () { failed = true }) if (failed) { fail('`setTimeout` callback was called before `wait`.') } Utils.clearTimeout(timeout) wait(100) if (failed) { fail('`setTimeout` callback was called after `wait`.') } } // --------------------------------------------------------------------------- function test_qmlTypeof_data () { return [ { component: 'import QtQuick 2.7; ListModel {}', result: true, type: 'QQmlListModel' }, { component: 'import QtQuick 2.7; ListView {}', result: true, type: 'QQuickListView' }, { component: 'import QtQuick 2.7; MouseArea {}', result: true, type: 'QQuickMouseArea' }, { component: 'import QtQuick 2.7; import QtQuick.Window 2.2; Window {}', result: true, type: 'QQuickWindowQmlImpl' } ] } function test_qmlTypeof (data) { var object = Qt.createQmlObject(data.component, testCase) verify(object) compare(Utils.qmlTypeof(object, data.type), data.result) } // --------------------------------------------------------------------------- function test_setTimeoutWithoutParent () { try { Utils.setTimeout(null, 0, function () { fail('`setTimeout` was called without parent.') }) } catch (e) { compare(e, 'Error: Qt.createQmlObject(): Missing parent object') } } function test_setTimeout_data () { return [ { time: 0 }, { time: 100 } ] } function test_setTimeout (data) { var failed = true Utils.setTimeout(testCase, data.time, function () { failed = false }) if (!failed) { fail('`setTimeout` callback was called before `wait`.') } wait(200) if (failed) { fail('`setTimeout` failed because callback it was not called in due course.') } } // =========================================================================== // GENERIC. // =========================================================================== function test_ensureArray_data () { return [ { input: [ 1, 2, 3 ], output: [ 1, 2, 3 ] }, { input: { toto: 4, ro: 5 }, output: [ 4, 5 ] }, { input: new Object(), output: [] }, { input: new Array(), output: [] }, { input: { a: 0, b: 1, c: 0 }, output: [ 0, 1, 0 ] } ] } function test_ensureArray (data) { // Use `sort` because transform a object in array hasn't a // guarantee ordering. compare(Utils.ensureArray(data.input).sort(), data.output.sort()) } // --------------------------------------------------------------------------- function test_execAll_data () { return [ { cb: function () { return 'failed' }, regex: /x/g, text: '', output: [] }, { cb: function (c, valid) { return !valid && c }, regex: /x/g, text: 'n', output: [ 'n' ] }, { cb: function (c, valid) { return valid && String.fromCharCode(c.charCodeAt(0) + 1) }, regex: /[a-z]/g, text: 'abcdefgh', output: [ 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i' ] }, { cb: function (n, valid) { return !valid ? '*' : Math.abs(n) }, regex: /\d+/g, text: 'abc 5 def -4 ghi 452-12', output: [ '*', 5, '*', 4, '*', 452, '*', 12 ] }, { regex: /candy-shop/g, text: 'candy-hop candy-shop cndy-shop candyshop', output: [ 'candy-hop ', 'candy-shop', ' cndy-shop candyshop' ] }, { cb: function (text, valid) { return valid ? text + ' Batman!' : text }, regex: /(?:na)+\.\.\./g, text: 'Nananana. Nanananananananana... Nanananananananana... Nananananananananananana...', output: [ 'Nananana. Na', 'nananananananana... Batman!', ' Na', 'nananananananana... Batman!', ' Na', 'nanananananananananana... Batman!' ] } ] } function test_execAll (data) { compare(Utils.execAll(data.regex, data.text, data.cb), data.output) } // --------------------------------------------------------------------------- function test_genRandomNumber_data () { return [ { min: 42, max: 3600 }, { min: 10, max: 100 }, { min: 58, max: 61 }, { min: 2, max: 3 } ] } function test_genRandomNumber (data) { Utils.times(10, function () { var n = Utils.genRandomNumber(data.min, data.max) compare(n >= data.min && n < data.max, true) }) } function test_genRandomNumberId () { compare(Utils.genRandomNumber(42, 42), 42) } // --------------------------------------------------------------------------- function test_genRandomNumberBetweenIntervals_data () { return [ { intervals: [ [ 1, 5 ] ] }, { intervals: [ [ 8, 9 ], [ 10, 15 ] ] }, { intervals: [ [ 1, 4 ], [ 8, 16 ], [ 22, 25 ] ] }, { intervals: [ [ 11, 12 ], [ 50, 80 ], [ 92, 93 ], [ 1000, 1100 ] ] }, { intervals: [ [ -5, -2 ] ] }, { intervals: [ [ -5, -2 ], [ 12, 14 ] ] }, { intervals: [ [ -127, -111 ], [ -35, -14 ], [ 1256, 1270 ], [ 10000, 10020 ] ] } ] } function test_genRandomNumberBetweenIntervals (data) { var intervals = data.intervals Utils.times(10, function () { var n = Utils.genRandomNumberBetweenIntervals(intervals) var soFarSoGood = false for (var i = 0; i < intervals.length; i++) { if (n >= intervals[i][0] && n < intervals[i][1]) { soFarSoGood = true break } } compare( soFarSoGood, true, 'The generated number cannot be found in a interval.' ) }) } // --------------------------------------------------------------------------- function test_getExtension_data () { return [ { input: 'foobar.baz', output: 'baz' }, { input: 'classe.george.abitbol', output: 'abitbol' }, { input: '', output: '' }, { input: 'cotcotcot', output: '' } ] } function test_getExtension (data) { compare(Utils.getExtension(data.input), data.output) } // --------------------------------------------------------------------------- function test_includes_data () { return [ // Test arrays. { input: [], value: 0, output: false }, { input: [ 1, 2, 3 ], value: 4, output: false }, { input: [ 6 ], value: 6, output: true }, { input: [ 4, 8, 'foo' ], value: 8, output: true }, { input: [ 12, NaN, 47 ], value: NaN, output: true }, { input: Array(1), value: undefined, output: true }, { input: [ 'a', 'b', 'c' ], startIndex: 1, value: 'a', output: false }, { input: [ 6, 5, 4, 9 ], startIndex: 3, value: 9, output: true }, // Test objects. { input: {}, value: 0, output: false }, { input: { a: 1, b: 2, c: 3 }, value: 4, output: false }, { input: { a: 6 }, value: 6, output: true }, { input: { a: 4, b: 8, c: 'foo' }, value: 8, output: true }, { input: { a: 12, b: NaN, c: 47 }, value: NaN, output: true }, { input: new Object(), value: undefined, output: false }, { input: { a: 'a', b: 'b', c: 'c' }, startIndex: 1, value: 'a', output: false }, { input: { a: 6, b: 5, c: 4, d: 9 }, startIndex: 3, value: 9, output: true }, ] } function test_includes (data) { compare( Utils.includes(data.input, data.value, data.startIndex), data.output ) } // --------------------------------------------------------------------------- function test_isArray_data () { return [ { input: [], output: true }, { input: {}, output: false }, { input: [ 6 ], output: true }, { input: /bar/, output: false }, { input: new Error, output: false }, { input: true, output: false }, { input: 42, output: false }, { input: new Array(), output: true }, { input: [ 15, new Date(), 'ij' ], output: true } ] } function test_isArray (data) { compare(Utils.isArray(data.input), data.output) } // --------------------------------------------------------------------------- function test_isString_data () { return [ { input: 'foo', output: true }, { input: Object('bar'), output: true }, { input: [ 0 ], output: false }, { input: /baz/, output: false }, { input: new Error, output: false }, { input: true, output: false }, { input: 42, output: false } ] } function test_isString (data) { compare(Utils.isString(data.input), data.output) } // --------------------------------------------------------------------------- function test_snakeToCamel_data () { return [ { input: 'foo_bar', output: 'fooBar' }, { input: 'george_abitbol', output: 'georgeAbitbol' }, { input: 'billTremendousAndHubert', output: 'billTremendousAndHubert' }, { input: 'foo_bAr_BAZ', output: 'fooBArBAZ' } ] } function test_snakeToCamel (data) { compare(Utils.snakeToCamel(data.input), data.output) } // --------------------------------------------------------------------------- function test_startsWith_data () { return [ { string: 'foo', searchStr: undefined, result: true }, { string: 'bar', searchStr: null, result: true }, { string: 'abitbol', searchStr: 'abitboll', result: false }, { string: '', searchStr: NaN, result: false }, { string: '', searchStr: '', result: true }, { string: '', searchStr: Infinity, result: false }, { string: '', searchStr: 0, result: false }, { string: 'george', searchStr: 'geo', result: true }, { string: 'george', searchStr: 'george', result: true }, { string: 'george', searchStr: 'georg', result: true }, { string: 'ruby', searchStr: '', result: true } ] } function test_startsWith (data) { compare( Utils.startsWith(data.string, data.searchStr), data.result ) } // --------------------------------------------------------------------------- function test_times1_data () { return [ { cb: function (n) { return n * 2 }, n: 10, output: [ 0, 2, 4, 6, 8, 10, 12, 14, 16, 18 ] }, { cb: function (n) { return n % 2 }, n: 6, output: [ 0, 1, 0, 1, 0, 1 ] } ] } function test_times1 (data) { compare(Utils.times(data.n, data.cb), data.output) } function test_times2 () { var sum = 0 Utils.times(5, function (i) { sum += (i + 1) }) compare(sum, 15) } } linphone-desktop-4.2.5/linphone-app/ui/views/000077500000000000000000000000001376717241300211645ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/ui/views/App/000077500000000000000000000000001376717241300217045ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/ui/views/App/Calls/000077500000000000000000000000001376717241300227425ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/ui/views/App/Calls/AbstractStartingCall.qml000066400000000000000000000067601376717241300275410ustar00rootroot00000000000000import QtQuick 2.7 import QtQuick.Layouts 1.3 import Common 1.0 import Linphone 1.0 import LinphoneUtils 1.0 import App.Styles 1.0 // ============================================================================= Rectangle { property var call default property alias _actionArea: actionArea.data property var _sipAddressObserver: SipAddressesModel.getSipAddressObserver(call.fullPeerAddress, call.fullLocalAddress) property alias showKeypad :telKeypadButton.visible // --------------------------------------------------------------------------- color: CallStyle.backgroundColor ColumnLayout { anchors { fill: parent topMargin: CallStyle.header.topMargin } spacing: 0 // ------------------------------------------------------------------------- // Contact & Call type (animation). // ------------------------------------------------------------------------- Column { Layout.fillWidth: true spacing: CallStyle.header.spacing ContactDescription { id: contactDescription height: CallStyle.header.contactDescription.height horizontalTextAlignment: Text.AlignHCenter sipAddress: call.peerAddress username: LinphoneUtils.getContactUsername(_sipAddressObserver) width: parent.width } BusyIndicator { anchors.horizontalCenter: parent.horizontalCenter color: CallStyle.header.busyIndicator.color height: CallStyle.header.busyIndicator.height width: CallStyle.header.busyIndicator.width visible: call.isOutgoing } } // ------------------------------------------------------------------------- // Contact visual. // ------------------------------------------------------------------------- Item { id: container Layout.fillHeight: true Layout.fillWidth: true Layout.margins: CallStyle.container.margins Avatar { id: avatar function _computeAvatarSize () { var height = container.height var width = container.width var size = height < CallStyle.container.avatar.maxSize && height > 0 ? height : CallStyle.container.avatar.maxSize return size < width ? size : width } anchors.centerIn: parent backgroundColor: CallStyle.container.avatar.backgroundColor image: _sipAddressObserver.contact && _sipAddressObserver.contact.vcard.avatar username: contactDescription.username height: _computeAvatarSize() width: height } } // ------------------------------------------------------------------------- // Buttons. // ------------------------------------------------------------------------- Item { id: actionArea Layout.fillWidth: true Layout.preferredHeight: CallStyle.actionArea.height } } ActionButton { id:telKeypadButton icon: 'tel_keypad' visible:false onClicked: telKeypad.visible = !telKeypad.visible anchors.left:parent.left anchors.top:parent.top iconSize: CallStyle.header.iconSize anchors.leftMargin: CallStyle.header.leftMargin anchors.topMargin: CallStyle.header.topMargin } // --------------------------------------------------------------------------- // TelKeypad. // --------------------------------------------------------------------------- TelKeypad { id: telKeypad call: parent.call visible: SettingsModel.showTelKeypadAutomatically } } linphone-desktop-4.2.5/linphone-app/ui/views/App/Calls/CallsWindow.js000066400000000000000000000062471376717241300255370ustar00rootroot00000000000000/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ // ============================================================================= // `CallsWindow.qml` Logic. // ============================================================================= .import Linphone 1.0 as Linphone .import 'qrc:/ui/scripts/Utils/utils.js' as Utils // ============================================================================= function handleClosing (close) { var callsList = Linphone.CallsListModel window.detachVirtualWindow() if (callsList.getRunningCallsNumber() === 0) { return } window.attachVirtualWindow(Utils.buildDialogUri('ConfirmDialog'), { descriptionText: qsTr('acceptClosingDescription') }, function (status) { if (status) { callsList.terminateAllCalls() window.close() } }) close.accepted = false } // ----------------------------------------------------------------------------- function openCallSipAddress () { window.attachVirtualWindow(Qt.resolvedUrl('Dialogs/CallSipAddress.qml')) } function openConferenceManager () { window.attachVirtualWindow(Qt.resolvedUrl('Dialogs/ConferenceManager.qml')) } // ----------------------------------------------------------------------------- // Used to get Component based from Call Status function getContent () { var call = window.call if (call == null) { return conference } var status = call.status if (status == null) { return calls.conferenceModel.count > 0 ? conference : null } var CallModel = Linphone.CallModel if (status === CallModel.CallStatusIncoming) { return incomingCall } if (status === CallModel.CallStatusOutgoing) { return outgoingCall } if (status === CallModel.CallStatusEnded) { return endedCall } return incall } // ----------------------------------------------------------------------------- function handleCallTransferAsked (call) { if (!call) { return } window.detachVirtualWindow() window.attachVirtualWindow(Qt.resolvedUrl('Dialogs/CallTransfer.qml'), { call: call }) } function windowMustBeClosed () { return Linphone.CallsListModel.rowCount() === 0 && !window.virtualWindowVisible } function tryToCloseWindow () { if (windowMustBeClosed()) { // Workaround, it's necessary to use a timeout because at last call termination // a segfault is emit in `QOpenGLContext::functions() const ()`. Utils.setTimeout(window, 0, function () { windowMustBeClosed() && window.close() }) } } linphone-desktop-4.2.5/linphone-app/ui/views/App/Calls/CallsWindow.qml000066400000000000000000000145201376717241300257050ustar00rootroot00000000000000import QtGraphicalEffects 1.0 import QtQuick 2.7 import QtQuick.Layouts 1.3 import Common 1.0 import Linphone 1.0 import App.Styles 1.0 import 'CallsWindow.js' as Logic // ============================================================================= Window { id: window // --------------------------------------------------------------------------- // `{}` is a workaround to avoid `TypeError: Cannot read property...` when calls list is empty readonly property var call: ( calls.selectedCall?calls.selectedCall:{ callError: '', isOutgoing: true, recording: false, localSas: '', peerAddress: '', localAddress: '', type: false, updating: true, videoEnabled: false }); readonly property bool chatIsOpened: !rightPaned.isClosed() // --------------------------------------------------------------------------- function openChat () { rightPaned.open() } function closeChat () { rightPaned.close() } function openConferenceManager () { Logic.openConferenceManager() } function setHeight (height) { window.height = (Window.screen && height > Window.screen.desktopAvailableHeight) ? Window.screen.desktopAvailableHeight : height } // --------------------------------------------------------------------------- minimumHeight: CallsWindowStyle.minimumHeight minimumWidth: CallsWindowStyle.minimumWidth title: qsTr('callsTitle') // --------------------------------------------------------------------------- onClosing: Logic.handleClosing(close) onDetachedVirtualWindow: Logic.tryToCloseWindow() // --------------------------------------------------------------------------- Paned { anchors.fill: parent defaultChildAWidth: CallsWindowStyle.callsList.defaultWidth maximumLeftLimit: CallsWindowStyle.callsList.maximumWidth minimumLeftLimit: CallsWindowStyle.callsList.minimumWidth // ------------------------------------------------------------------------- // Calls list. // ------------------------------------------------------------------------- childA: Rectangle { anchors.fill: parent color: CallsWindowStyle.callsList.color ColumnLayout { anchors.fill: parent spacing: 0 Item { Layout.fillWidth: true Layout.preferredHeight: CallsWindowStyle.callsList.header.height visible: SettingsModel.outgoingCallsEnabled || SettingsModel.conferenceEnabled LinearGradient { anchors.fill: parent start: Qt.point(0, 0) end: Qt.point(0, height) gradient: Gradient { GradientStop { position: 0.0; color: CallsWindowStyle.callsList.header.color1 } GradientStop { position: 1.0; color: CallsWindowStyle.callsList.header.color2 } } } ActionBar { anchors { left: parent.left leftMargin: CallsWindowStyle.callsList.header.leftMargin verticalCenter: parent.verticalCenter } iconSize: CallsWindowStyle.callsList.header.iconSize ActionButton { icon: 'new_call' visible: SettingsModel.outgoingCallsEnabled onClicked: Logic.openCallSipAddress() } ActionButton { icon: 'new_conference' visible: SettingsModel.conferenceEnabled onClicked: Logic.openConferenceManager() } } } Calls { id: calls Layout.fillHeight: true Layout.fillWidth: true conferenceModel: ConferenceModel {} model: CallsListProxyModel {} } } } // ------------------------------------------------------------------------- // Content. // ------------------------------------------------------------------------- childB: Paned { id: rightPaned anchors.fill: parent closingEdge: Qt.RightEdge defaultClosed: true minimumLeftLimit: CallsWindowStyle.call.minimumWidth minimumRightLimit: CallsWindowStyle.chat.minimumWidth resizeAInPriority: true // ----------------------------------------------------------------------- Component { id: incomingCall IncomingCall { call: window.call } } Component { id: outgoingCall OutgoingCall { call: window.call } } Component { id: incall Incall { call: window.call } } Component { id: endedCall EndedCall { call: window.call } } Component { id: chat Chat { proxyModel: ChatProxyModel { Component.onCompleted: { if (!SettingsModel.chatEnabled) { setEntryTypeFilter(ChatModel.CallEntry) } } peerAddress: (call?call.peerAddress:'') localAddress: (call?call.localAddress:'') fullPeerAddress: (call?call.fullPeerAddress:peerAddress) fullLocalAddress: (call?call.fullLocalAddress:localAddress) } Connections { target: SettingsModel onChatEnabledChanged: proxyModel.setEntryTypeFilter(status ? ChatModel.GenericEntry : ChatModel.CallEntry) } } } Component { id: conference Conference { conferenceModel: calls.conferenceModel } } // ----------------------------------------------------------------------- childA: Loader { anchors.fill: parent sourceComponent: Logic.getContent() onSourceComponentChanged: {rightPaned.childAItem.update()}// Force update when loading a new Content. It's just to be sure } childB: Loader { anchors.fill: parent sourceComponent: window.call && window.call.peerAddress && window.call.localAddress ? chat : null } } } // --------------------------------------------------------------------------- // Handle transfer. // Handle count changed. Not on proxy model!!! // --------------------------------------------------------------------------- Connections { target: CallsListModel onCallTransferAsked: Logic.handleCallTransferAsked(callModel) onRowsRemoved: Logic.tryToCloseWindow() } } linphone-desktop-4.2.5/linphone-app/ui/views/App/Calls/Conference.qml000066400000000000000000000157411376717241300255340ustar00rootroot00000000000000import QtQuick 2.7 import QtQuick.Layouts 1.3 import Common 1.0 import Common.Styles 1.0 import Linphone 1.0 import LinphoneUtils 1.0 import App.Styles 1.0 // ============================================================================= Rectangle { id: conference property var conferenceModel // --------------------------------------------------------------------------- color: CallStyle.backgroundColor // --------------------------------------------------------------------------- ColumnLayout { anchors { fill: parent topMargin: CallStyle.header.topMargin } spacing: 0 // ------------------------------------------------------------------------- // Conference info. // ------------------------------------------------------------------------- Item { id: info Layout.fillWidth: true Layout.leftMargin: CallStyle.header.leftMargin Layout.rightMargin: CallStyle.header.rightMargin Layout.preferredHeight: ConferenceStyle.description.height ActionBar { id: leftActions anchors.left: parent.left iconSize: CallStyle.header.iconSize } Text { id: conferenceDescription anchors.centerIn: parent horizontalAlignment: Text.AlignHCenter text: qsTr('conferenceTitle') color: ConferenceStyle.description.color font { bold: true pointSize: ConferenceStyle.description.pointSize } height: parent.height width: parent.width - rightActions.width - leftActions.width - ConferenceStyle.description.width } // ----------------------------------------------------------------------- // Video actions. // ----------------------------------------------------------------------- ActionBar { id: rightActions anchors.right: parent.right iconSize: CallStyle.header.iconSize ActionSwitch { enabled: conference.conferenceModel.recording icon: 'record' useStates: false onClicked: !enabled ? conference.conferenceModel.startRecording() : conference.conferenceModel.stopRecording() } } } // ------------------------------------------------------------------------- // Contacts visual. // ------------------------------------------------------------------------- Item { id: container Layout.fillWidth: true Layout.fillHeight: true Layout.margins: CallStyle.container.margins GridView { id: grid anchors.fill: parent cellHeight: ConferenceStyle.grid.cell.height cellWidth: ConferenceStyle.grid.cell.width model: conference.conferenceModel delegate: Item { height: grid.cellHeight width: grid.cellWidth Column { readonly property string sipAddress: $call.peerAddress property var _sipAddressObserver : SipAddressesModel.getSipAddressObserver($call.peerAddress, $call.localAddress) anchors { fill: parent margins: ConferenceStyle.grid.spacing } spacing: ConferenceStyle.grid.cell.spacing ContactDescription { id: contactDescription height: ConferenceStyle.grid.cell.contactDescription.height width: parent.width horizontalTextAlignment: Text.AlignHCenter sipAddress: parent.sipAddress username: LinphoneUtils.getContactUsername(parent._sipAddressObserver) } IncallAvatar { readonly property int size: Math.min( parent.width, parent.height - contactDescription.height - parent.spacing ) anchors.horizontalCenter: parent.horizontalCenter call: $call onCallChanged: if(!call) conference.conferenceModel.invalidate() height: size width: size BusyIndicator { anchors { horizontalCenter: parent.horizontalCenter verticalCenter: parent.verticalCenter } color: CallStyle.header.busyIndicator.color height: CallStyle.header.busyIndicator.height width: CallStyle.header.busyIndicator.width visible: $call && $call.status === CallModel.CallStatusOutgoing } } } VuMeter { anchors { bottom: parent.bottom left: parent.left leftMargin: ConferenceStyle.grid.spacing bottomMargin: ConferenceStyle.grid.spacing } enabled:!$call.speakerMuted Timer { interval: 50 repeat: true running: true onTriggered: parent.value = $call.speakerVu } } MouseArea{ anchors.fill:parent onClicked:$call.toggleSpeakerMute() } } } } // ------------------------------------------------------------------------- // Action Buttons. // ------------------------------------------------------------------------- Item { Layout.fillWidth: true Layout.preferredHeight: CallStyle.actionArea.height GridLayout { anchors { left: parent.left leftMargin: CallStyle.actionArea.leftButtonsGroupMargin verticalCenter: parent.verticalCenter } columns: incall.width < CallStyle.actionArea.lowWidth ? 2 : 4 rowSpacing: ActionBarStyle.spacing Row { spacing: CallStyle.actionArea.vu.spacing VuMeter { Timer { interval: 50 repeat: true running: micro.enabled onTriggered: parent.value = conference.conferenceModel.microVu } enabled: micro.enabled } ActionSwitch { id: micro enabled: !conference.conferenceModel.microMuted icon: 'micro' iconSize: CallStyle.actionArea.iconSize onClicked: conference.conferenceModel.microMuted = !conference.conferenceModel.microMuted } } } ActionBar { anchors { right: parent.right rightMargin: CallStyle.actionArea.rightButtonsGroupMargin verticalCenter: parent.verticalCenter } iconSize: CallStyle.actionArea.iconSize ActionSwitch { enabled: conference.conferenceModel.isInConf icon: 'pause' onClicked: { var model = conference.conferenceModel if (model.isInConf) { model.leave() } else { model.join() } } } ActionButton { icon: 'hangup' onClicked: conference.conferenceModel.terminate() } } } } } linphone-desktop-4.2.5/linphone-app/ui/views/App/Calls/Dialogs/000077500000000000000000000000001376717241300243245ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/ui/views/App/Calls/Dialogs/CallSipAddress.qml000066400000000000000000000036731376717241300277050ustar00rootroot00000000000000import QtQuick 2.7 import QtQuick.Layouts 1.3 import Common 1.0 import Linphone 1.0 import App.Styles 1.0 // ============================================================================= DialogPlus { buttons: [ TextButtonA { text: qsTr('cancel') onClicked: exit(0) } ] centeredButtons: true descriptionText: qsTr('callSipAddressDescription') height: CallSipAddressStyle.height width: CallSipAddressStyle.width // --------------------------------------------------------------------------- ColumnLayout { anchors.fill: parent spacing: 0 // ------------------------------------------------------------------------- // Address selector. // ------------------------------------------------------------------------- Item { Layout.fillHeight: true Layout.fillWidth: true ColumnLayout { anchors.fill: parent spacing: CallSipAddressStyle.spacing TextField { id: filter Layout.fillWidth: true icon: 'search' onTextChanged: sipAddressesModel.setFilter(text) } ScrollableListViewField { Layout.fillHeight: true Layout.fillWidth: true SipAddressesView { anchors.fill: parent actions: [{ icon: 'video_call', handler: function (entry) { CallsListModel.launchVideoCall(entry.sipAddress) exit(1) }, visible: SettingsModel.videoSupported }, { icon: 'call', handler: function (entry) { CallsListModel.launchAudioCall(entry.sipAddress) exit(1) } }] genSipAddress: filter.text model: SipAddressesProxyModel { id: sipAddressesModel } onEntryClicked: actions[0].handler(entry) } } } } } } linphone-desktop-4.2.5/linphone-app/ui/views/App/Calls/Dialogs/CallTransfer.qml000066400000000000000000000044121376717241300274200ustar00rootroot00000000000000import QtQuick 2.7 import QtQuick.Layouts 1.3 import Common 1.0 import Linphone 1.0 import App.Styles 1.0 // ============================================================================= DialogPlus { id: callTransfer // --------------------------------------------------------------------------- property var call // --------------------------------------------------------------------------- buttons: [ TextButtonA { text: qsTr('cancel') onClicked: exit(0) } ] centeredButtons: true descriptionText: qsTr('callTransferDescription') height: CallTransferStyle.height width: CallTransferStyle.width onCallChanged: !call && exit(0) // --------------------------------------------------------------------------- ColumnLayout { anchors.fill: parent spacing: 0 // ------------------------------------------------------------------------- // Contact. // ------------------------------------------------------------------------- Contact { Layout.fillWidth: true entry: SipAddressesModel.getSipAddressObserver(call ? call.fullPeerAddress : '', call ? call.fullLocalAddress : '') } // ------------------------------------------------------------------------- // Address selector. // ------------------------------------------------------------------------- Item { Layout.fillHeight: true Layout.fillWidth: true ColumnLayout { anchors.fill: parent spacing: CallTransferStyle.spacing TextField { id: filter Layout.fillWidth: true icon: 'search' onTextChanged: sipAddressesModel.setFilter(text) } ScrollableListViewField { Layout.fillHeight: true Layout.fillWidth: true SipAddressesView { anchors.fill: parent actions: [{ icon: 'transfer', handler: function (entry) { callTransfer.call.transferTo(entry.sipAddress) exit(1) } }] genSipAddress: filter.text model: SipAddressesProxyModel { id: sipAddressesModel } onEntryClicked: actions[0].handler(entry) } } } } } } linphone-desktop-4.2.5/linphone-app/ui/views/App/Calls/Dialogs/ConferenceManager.qml000066400000000000000000000065251376717241300304110ustar00rootroot00000000000000import QtQuick 2.7 import QtQuick.Layouts 1.3 import Common 1.0 import Linphone 1.0 import App.Styles 1.0 // ============================================================================= DialogPlus { id: conferenceManager readonly property int maxParticipants: 20 readonly property int minParticipants: 1 buttons: [ TextButtonA { text: qsTr('cancel') onClicked: exit(0) }, TextButtonB { enabled: toAddView.count >= conferenceManager.minParticipants text: qsTr('confirm') onClicked: { conferenceHelperModel.toAdd.update() exit(1) } } ] centeredButtons: true descriptionText: qsTr('conferenceManagerDescription') height: ConferenceManagerStyle.height width: ConferenceManagerStyle.width // --------------------------------------------------------------------------- RowLayout { anchors.fill: parent spacing: 0 // ------------------------------------------------------------------------- // Address selector. // ------------------------------------------------------------------------- Item { Layout.fillHeight: true Layout.fillWidth: true ColumnLayout { anchors.fill: parent spacing: ConferenceManagerStyle.columns.selector.spacing TextField { id: filter Layout.fillWidth: true icon: 'search' onTextChanged: conferenceHelperModel.setFilter(text) } ScrollableListViewField { Layout.fillHeight: true Layout.fillWidth: true readOnly: toAddView.count >= conferenceManager.maxParticipants SipAddressesView { anchors.fill: parent actions: [{ icon: 'transfer', handler: function (entry) { conferenceHelperModel.toAdd.addToConference(entry.sipAddress) } }] genSipAddress: filter.text model: ConferenceHelperModel { id: conferenceHelperModel } onEntryClicked: actions[0].handler(entry) } } } } // ------------------------------------------------------------------------- // Separator. // ------------------------------------------------------------------------- Rectangle { Layout.fillHeight: true Layout.leftMargin: ConferenceManagerStyle.columns.separator.leftMargin Layout.preferredWidth: ConferenceManagerStyle.columns.separator.width Layout.rightMargin: ConferenceManagerStyle.columns.separator.rightMargin color: ConferenceManagerStyle.columns.separator.color } // ------------------------------------------------------------------------- // See and remove selected addresses. // ------------------------------------------------------------------------- ScrollableListViewField { Layout.fillHeight: true Layout.fillWidth: true Layout.topMargin: filter.height + ConferenceManagerStyle.columns.selector.spacing SipAddressesView { id: toAddView anchors.fill: parent actions: [{ icon: 'cancel', handler: function (entry) { model.removeFromConference(entry.sipAddress) } }] model: conferenceHelperModel.toAdd onEntryClicked: actions[0].handler(entry) } } } } linphone-desktop-4.2.5/linphone-app/ui/views/App/Calls/Dialogs/MultimediaParameters.qml000066400000000000000000000070071376717241300311610ustar00rootroot00000000000000import QtQuick 2.7 import QtQuick.Controls 2.7 import QtQuick.Layouts 1.3 import Common 1.0 import Common.Styles 1.0 import Linphone 1.0 import Utils 1.0 import App.Styles 1.0 // ============================================================================= DialogPlus { property var call // --------------------------------------------------------------------------- buttons: [ TextButtonB { text: qsTr('ok') onClicked: { call.updateStreams() exit(0) } } ] centeredButtons: true height: MultimediaParametersStyle.height width: MultimediaParametersStyle.width onCallChanged: !call && exit(0) // --------------------------------------------------------------------------- Column { anchors.fill: parent spacing: MultimediaParametersStyle.column.spacing RowLayout { spacing: MultimediaParametersStyle.column.entry.spacing width: parent.width Icon { Layout.alignment: Qt.AlignTop Layout.preferredHeight: ComboBoxStyle.background.height icon: 'speaker' iconSize: MultimediaParametersStyle.column.entry.iconSize } Column { Layout.fillWidth: true spacing: MultimediaParametersStyle.column.entry.spacing2 ComboBox { currentIndex: Utils.findIndex(model, function (device) { return device === SettingsModel.playbackDevice }) model: SettingsModel.playbackDevices width: parent.width onActivated: SettingsModel.playbackDevice = model[index] } Slider { id: playbackSlider width: parent.width Component.onCompleted: value = call.speakerVolumeGain onPositionChanged: call.speakerVolumeGain = position ToolTip { parent: playbackSlider.handle visible: playbackSlider.pressed text: (playbackSlider.value * 100).toFixed(0) + " %" } } } } RowLayout { spacing: MultimediaParametersStyle.column.entry.spacing width: parent.width Icon { Layout.alignment: Qt.AlignTop Layout.preferredHeight: ComboBoxStyle.background.height icon: 'micro' iconSize: MultimediaParametersStyle.column.entry.iconSize } Column { Layout.fillWidth: true spacing: MultimediaParametersStyle.column.entry.spacing2 ComboBox { currentIndex: Utils.findIndex(model, function (device) { return device === SettingsModel.captureDevice }) model: SettingsModel.captureDevices width: parent.width onActivated: SettingsModel.captureDevice = model[index] } Slider { id: captureSlider width: parent.width Component.onCompleted: value = call.microVolumeGain onPositionChanged: call.microVolumeGain = position ToolTip { parent: captureSlider.handle visible: captureSlider.pressed text: "+ " + (captureSlider.value * 100).toFixed(0) + " %" } } } } RowLayout { spacing: MultimediaParametersStyle.column.entry.spacing width: parent.width Icon { icon: 'camera' iconSize: MultimediaParametersStyle.column.entry.iconSize } ComboBox { Layout.fillWidth: true currentIndex: Number(Utils.findIndex(model, function (device) { return device === SettingsModel.videoDevice })) model: SettingsModel.videoDevices onActivated: SettingsModel.videoDevice = model[index] } } } } linphone-desktop-4.2.5/linphone-app/ui/views/App/Calls/EndedCall.qml000066400000000000000000000043351376717241300252750ustar00rootroot00000000000000import QtQuick 2.7 import QtQuick.Layouts 1.3 import Linphone 1.0 import LinphoneUtils 1.0 import Utils 1.0 import App.Styles 1.0 import 'Incall.js' as Logic // ============================================================================= Rectangle { id: endedCall property var call property var _sipAddressObserver: SipAddressesModel.getSipAddressObserver(call ? call.fullPeerAddress : '', call ? call.fullLocalAddress : '') // --------------------------------------------------------------------------- color: CallStyle.backgroundColor ColumnLayout { anchors { fill: parent topMargin: CallStyle.header.topMargin } spacing: 0 ContactDescription { id: contactDescription Layout.fillWidth: true Layout.preferredHeight: CallStyle.header.contactDescription.height horizontalTextAlignment: Text.AlignHCenter sipAddress: _sipAddressObserver.peerAddress username: LinphoneUtils.getContactUsername(_sipAddressObserver) } Text { Layout.fillWidth: true color: CallStyle.header.elapsedTime.color font.pointSize: CallStyle.header.elapsedTime.pointSize horizontalAlignment: Text.AlignHCenter text: { var call = endedCall.call return call ? Utils.formatElapsedTime(call.duration) : 0 } } Item { id: container Layout.fillWidth: true Layout.fillHeight: true Layout.margins: CallStyle.container.margins Avatar { anchors.centerIn: parent backgroundColor: CallStyle.container.avatar.backgroundColor image: _sipAddressObserver.contact && _sipAddressObserver.contact.vcard.avatar username: contactDescription.username height: Logic.computeAvatarSize(CallStyle.container.avatar.maxSize) width: height } } Item { Layout.fillWidth: true Layout.preferredHeight: CallStyle.actionArea.height Text { color: CallStyle.actionArea.callError.color font.pointSize: CallStyle.actionArea.callError.pointSize horizontalAlignment: Text.AlignHCenter width: parent.width text: { var call = endedCall.call return call ? call.callError : '' } } } } } linphone-desktop-4.2.5/linphone-app/ui/views/App/Calls/Incall.js000066400000000000000000000105151376717241300245040ustar00rootroot00000000000000/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ // ============================================================================= // `Incall.qml` Logic. // ============================================================================= .import DesktopTools 1.0 as DesktopTools .import Linphone 1.0 as Linphone .import 'qrc:/ui/scripts/Utils/utils.js' as Utils // ============================================================================= function computeAvatarSize (maxSize) { var height = container.height var width = container.width var size = height < maxSize && height > 0 ? height : maxSize return size < width ? size : width } function handleCallStatisticsClosed () { // Prevent many clicks on call statistics button. Utils.setTimeout(callQuality, 500, function () { callQuality.enabled = true }) } function handleCameraFirstFrameReceived (width, height) { // Cell phone??? if (height > width) { return } var ratio = container.width / (width / (height / container.height)) var diff = container.height * ratio - container.height if (diff < 0) { return } window.setHeight(window.height + diff) } function handleStatusChanged (status) { if (status === Linphone.CallModel.CallStatusEnded) { var fullscreen = incall._fullscreen if (fullscreen) { // Timeout => Avoid dead lock on mac. Utils.setTimeout(window, 0, fullscreen.exit) } telKeypad.visible = false callStatistics.close() } } function handleVideoRequested () { var call = incall.call if (window.virtualWindowVisible || !Linphone.SettingsModel.videoSupported) { call.rejectVideoRequest() return } // Close dialog after 10s. var timeout = Utils.setTimeout(incall, 10000, function () { call.statusChanged.disconnect(endedHandler) window.detachVirtualWindow() call.rejectVideoRequest() }) // Close dialog if call is ended. var endedHandler = function (status) { if (status === Linphone.CallModel.CallStatusEnded) { Utils.clearTimeout(timeout) call.statusChanged.disconnect(endedHandler) window.detachVirtualWindow() } } call.statusChanged.connect(endedHandler) // Ask video to user. window.attachVirtualWindow(Utils.buildDialogUri('ConfirmDialog'), { descriptionText: qsTr('acceptVideoDescription'), }, function (status) { Utils.clearTimeout(timeout) call.statusChanged.disconnect(endedHandler) if (status) { call.acceptVideoRequest() } else { call.rejectVideoRequest() } }) } function makeReadableSecuredString (securedString) { if (!securedString || !securedString.length) { return qsTr('callNotSecured') } return qsTr('securedStringFormat').replace('%1', securedString) } function openCallStatistics () { callQuality.enabled = false callStatistics.open() } function openMediaParameters (window, incall) { window.attachVirtualWindow(Qt.resolvedUrl('Dialogs/MultimediaParameters.qml'), { call: incall.call }) } function showFullscreen (position) { if (incall._fullscreen) { return } DesktopTools.DesktopTools.screenSaverStatus = false incall._fullscreen = Utils.openWindow(Qt.resolvedUrl('IncallFullscreenWindow.qml'), window, { properties: { caller: incall, x:position.x, y:position.y, width:window.width, height:window.height } }, true) } function updateCallQualityIcon (callQuality,call) { var quality = call.quality callQuality.icon = 'call_quality_' + ( // Note: `quality` is in the [0, 5] interval. // It's necessary to map in the `call_quality_` interval. ([0, 3]) quality >= 0 ? Math.round(quality / (5 / 3)) : 0 ) } linphone-desktop-4.2.5/linphone-app/ui/views/App/Calls/Incall.qml000066400000000000000000000263231376717241300246650ustar00rootroot00000000000000import QtQuick 2.7 import QtQuick.Controls 2.2 import QtQuick.Layouts 1.3 import Common 1.0 import Common.Styles 1.0 import Linphone 1.0 import LinphoneUtils 1.0 import Utils 1.0 import App.Styles 1.0 import 'Incall.js' as Logic // ============================================================================= Rectangle { id: incall // --------------------------------------------------------------------------- // Used by `IncallFullscreenWindow.qml`. readonly property bool cameraActivated: cameraLoader.status !== Loader.Null || cameraPreviewLoader.status !== Loader.Null property var call property var _sipAddressObserver: SipAddressesModel.getSipAddressObserver(call.fullPeerAddress, call.fullLocalAddress) property var _fullscreen: null // --------------------------------------------------------------------------- color: CallStyle.backgroundColor anchors.fill:parent // --------------------------------------------------------------------------- Connections { target: call onCameraFirstFrameReceived: Logic.handleCameraFirstFrameReceived(width, height) onStatusChanged: Logic.handleStatusChanged (status) onVideoRequested: Logic.handleVideoRequested() } ColumnLayout { anchors { fill: parent topMargin: CallStyle.header.topMargin } spacing: 0 // ------------------------------------------------------------------------- // Call info. // ------------------------------------------------------------------------- Item { id: info Layout.fillWidth: true Layout.leftMargin: CallStyle.header.leftMargin Layout.rightMargin: CallStyle.header.rightMargin Layout.preferredHeight: CallStyle.header.contactDescription.height ActionBar { id: leftActions anchors.left: parent.left iconSize: CallStyle.header.iconSize ActionButton { id: callQuality icon: 'call_quality_0' useStates: false onClicked: Logic.openCallStatistics() // See: http://www.linphone.org/docs/liblinphone/group__call__misc.html#ga62c7d3d08531b0cc634b797e273a0a73 Timer { interval: 500 repeat: true running: true triggeredOnStart: true onTriggered: Logic.updateCallQualityIcon(callQuality, call) } CallStatistics { id: callStatistics call: incall.call width: container.width relativeTo: callQuality relativeY: CallStyle.header.stats.relativeY onClosed: Logic.handleCallStatisticsClosed() } } ActionButton { icon: 'tel_keypad' onClicked: telKeypad.visible = !telKeypad.visible } ActionButton { id: callSecure icon: incall.call.isSecured ? 'call_chat_secure' : 'call_chat_unsecure' onClicked: zrtp.visible = (incall.call.encryption === CallModel.CallEncryptionZrtp) TooltipArea { text: Logic.makeReadableSecuredString(incall.call.securedString) } } } ContactDescription { id: contactDescription anchors.centerIn: parent horizontalTextAlignment: Text.AlignHCenter sipAddress: _sipAddressObserver.peerAddress username: LinphoneUtils.getContactUsername(_sipAddressObserver) height: parent.height width: parent.width - rightActions.width - leftActions.width Text { id: elapsedTime color: CallStyle.header.elapsedTime.color font.pointSize: CallStyle.header.elapsedTime.pointSize horizontalAlignment: Text.AlignHCenter width: parent.width Timer { interval: 1000 repeat: true running: true triggeredOnStart: true onTriggered: {elapsedTime.text = Utils.formatElapsedTime(call.duration);} } } } // ----------------------------------------------------------------------- // Video actions. // ----------------------------------------------------------------------- ActionBar { id: rightActions anchors.right: parent.right iconSize: CallStyle.header.buttonIconSize ActionButton { icon: 'screenshot' visible: incall.call.videoEnabled onClicked: incall.call.takeSnapshot() TooltipArea { text: qsTr('takeSnapshotLabel') } } ActionSwitch { id: recordingSwitch enabled: incall.call.recording icon: 'record' useStates: false visible: SettingsModel.callRecorderEnabled onClicked: { var call = incall.call return !enabled ? call.startRecording() : call.stopRecording() } onVisibleChanged: { if (!visible) { call.stopRecording() } } TooltipArea { text: !recordingSwitch.enabled ? qsTr('startRecordingLabel') : qsTr('stopRecordingLabel') } } ActionButton { icon: 'fullscreen' visible: incall.call.videoEnabled onClicked: Logic.showFullscreen(contactDescription.mapToGlobal(0,0)) } } } // ------------------------------------------------------------------------- // Contact visual. // ------------------------------------------------------------------------- Item { id: container Layout.fillWidth: true Layout.fillHeight: true Layout.margins: CallStyle.container.margins Component { id: avatar IncallAvatar { call: incall.call height: Logic.computeAvatarSize(CallStyle.container.avatar.maxSize) width: height } } Loader { id: cameraLoader anchors.centerIn: parent active: incall.call.videoEnabled && !_fullscreen sourceComponent: camera Component { id: camera Camera { call: incall.call height: container.height width: container.width } } } Loader { anchors.centerIn: parent active: !call.videoEnabled || _fullscreen sourceComponent: avatar } } // ------------------------------------------------------------------------- // Zrtp. // ------------------------------------------------------------------------- ZrtpTokenAuthentication { id: zrtp Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter Layout.margins: CallStyle.container.margins call: incall.call visible: !call.isSecured && call.encryption !== CallModel.CallEncryptionNone z: Constants.zPopup } // ------------------------------------------------------------------------- // Action Buttons. // ------------------------------------------------------------------------- Item { Layout.fillWidth: true Layout.preferredHeight: CallStyle.actionArea.height GridLayout { anchors { left: parent.left leftMargin: CallStyle.actionArea.leftButtonsGroupMargin verticalCenter: parent.verticalCenter } columns: incall.width < CallStyle.actionArea.lowWidth ? 2 : 4 rowSpacing: ActionBarStyle.spacing Row { spacing: CallStyle.actionArea.vu.spacing visible: SettingsModel.muteMicrophoneEnabled VuMeter { Timer { interval: 50 repeat: true running: micro.enabled onTriggered: parent.value = incall.call.microVu } enabled: micro.enabled } ActionSwitch { id: micro enabled: !call.microMuted icon: 'micro' iconSize: CallStyle.actionArea.iconSize onClicked: incall.call.microMuted = enabled } } Row { spacing: CallStyle.actionArea.vu.spacing VuMeter { Timer { interval: 50 repeat: true running: speaker.enabled onTriggered: parent.value = incall.call.speakerVu } enabled: speaker.enabled } ActionSwitch { id: speaker enabled: !call.speakerMuted icon: 'speaker' iconSize: CallStyle.actionArea.iconSize onClicked: incall.call.speakerMuted = enabled } } ActionSwitch { enabled: incall.call.videoEnabled icon: 'camera' iconSize: CallStyle.actionArea.iconSize updating: incall.call.updating visible: SettingsModel.videoSupported onClicked: incall.call.videoEnabled = !enabled TooltipArea { text: qsTr('pendingRequestLabel') visible: parent.updating } } ActionButton { Layout.preferredHeight: CallStyle.actionArea.iconSize Layout.preferredWidth: CallStyle.actionArea.iconSize icon: 'options' iconSize: CallStyle.actionArea.iconSize onClicked: Logic.openMediaParameters(window, incall) } } // ----------------------------------------------------------------------- // Preview. // ----------------------------------------------------------------------- Loader { id: cameraPreviewLoader anchors.centerIn: parent height: CallStyle.actionArea.userVideo.height width: CallStyle.actionArea.userVideo.width active: incall.width >= CallStyle.actionArea.lowWidth && incall.call.videoEnabled && !_fullscreen sourceComponent: cameraPreview Component { id: cameraPreview Camera { anchors.fill: parent call: incall.call isPreview: true } } } ActionBar { id: bottomActions anchors { right: parent.right rightMargin: CallStyle.actionArea.rightButtonsGroupMargin verticalCenter: parent.verticalCenter } iconSize: CallStyle.actionArea.iconSize ActionSwitch { enabled: !call.pausedByUser icon: 'pause' updating: incall.call.updating visible: SettingsModel.callPauseEnabled onClicked: incall.call.pausedByUser = enabled TooltipArea { text: qsTr('pendingRequestLabel') visible: parent.updating } } ActionButton { icon: 'hangup' onClicked: incall.call.terminate() } ActionButton { icon: SettingsModel.chatEnabled ? 'chat' : 'history' onClicked: { if (window.chatIsOpened) { window.closeChat() } else { window.openChat() } } } } } } // --------------------------------------------------------------------------- // TelKeypad. // --------------------------------------------------------------------------- TelKeypad { id: telKeypad call: incall.call visible: SettingsModel.showTelKeypadAutomatically } } linphone-desktop-4.2.5/linphone-app/ui/views/App/Calls/IncallAvatar.qml000066400000000000000000000022731376717241300260220ustar00rootroot00000000000000import QtQuick 2.7 import Linphone 1.0 import LinphoneUtils 1.0 import App.Styles 1.0 // ============================================================================= Avatar { property var call readonly property var _sipAddressObserver: SipAddressesModel.getSipAddressObserver(call.fullPeerAddress, call.fullLocalAddress) readonly property var _username: LinphoneUtils.getContactUsername(_sipAddressObserver) backgroundColor: CallStyle.container.avatar.backgroundColor foregroundColor: call.status === CallModel.CallStatusPaused ? CallStyle.container.pause.color : 'transparent' image: { var contact = _sipAddressObserver.contact return contact && contact.vcard.avatar } username: call.status === CallModel.CallStatusPaused ? '' : _username Text { anchors.fill: parent color: CallStyle.container.pause.text.color // `|| 1` => `pointSize` must be greater than 0. font.pointSize: (width / CallStyle.container.pause.text.pointSizeFactor) || 1 horizontalAlignment: Text.AlignHCenter verticalAlignment: Text.AlignVCenter text: '▐ ▌' textFormat: Text.RichText visible: call.status === CallModel.CallStatusPaused } } linphone-desktop-4.2.5/linphone-app/ui/views/App/Calls/IncallFullscreenWindow.qml000066400000000000000000000271521376717241300301010ustar00rootroot00000000000000import QtQuick 2.7 import QtQuick.Controls 2.2 import QtQuick.Layouts 1.3 import QtQuick.Window 2.2 import Common 1.0 import Common.Styles 1.0 import DesktopTools 1.0 import Linphone 1.0 import LinphoneUtils 1.0 import Utils 1.0 import App.Styles 1.0 import 'Incall.js' as Logic // ============================================================================= Window { id: window // --------------------------------------------------------------------------- property var call property var caller property bool hideButtons: false // --------------------------------------------------------------------------- function exit (cb) { DesktopTools.screenSaverStatus = true // `exit` is called by `Incall.qml`. // The `window` id can be null if the window was closed in this view. if (!window) { return } if(!window.close() && parent) parent.close() if (cb) { cb() } } // --------------------------------------------------------------------------- onCallChanged: if(!call) window.exit() Component.onCompleted: { window.call = caller.call } // --------------------------------------------------------------------------- Shortcut { sequence: StandardKey.Close onActivated: window.exit() } // --------------------------------------------------------------------------- Rectangle { id:container anchors.fill: parent color: '#000000' // Not a style. focus: true Keys.onEscapePressed: window.exit() Loader { anchors.fill: parent active: { var caller = window.caller return caller && !caller.cameraActivated } sourceComponent: camera Component { id: camera Camera { call: window.call } } } // ------------------------------------------------------------------------- // Handle mouse move / Hide buttons. // ------------------------------------------------------------------------- MouseArea { Timer { id: hideButtonsTimer interval: 5000 running: true onTriggered: hideButtons = true } anchors.fill: parent acceptedButtons: Qt.NoButton propagateComposedEvents: true cursorShape: Qt.ArrowCursor onEntered: hideButtonsTimer.start() onExited: hideButtonsTimer.stop() onPositionChanged: { hideButtonsTimer.stop() hideButtons = false hideButtonsTimer.start() } } ColumnLayout { anchors { fill: parent topMargin: CallStyle.header.topMargin } spacing: 0 // ----------------------------------------------------------------------- // Call info. // ----------------------------------------------------------------------- Item { id: info Layout.alignment: Qt.AlignTop Layout.fillWidth: true Layout.leftMargin: CallStyle.header.leftMargin Layout.preferredHeight: CallStyle.header.contactDescription.height Layout.rightMargin: CallStyle.header.rightMargin ActionBar { anchors.left: parent.left iconSize: CallStyle.header.iconSize visible: !hideButtons ActionButton { id: callQuality icon: 'call_quality_0' iconSize: parent.iconSize useStates: false onClicked: Logic.openCallStatistics() // See: http://www.linphone.org/docs/liblinphone/group__call__misc.html#ga62c7d3d08531b0cc634b797e273a0a73 Timer { interval: 5000 repeat: true running: true triggeredOnStart: true onTriggered: Logic.updateCallQualityIcon(callQuality, window.call) } CallStatistics { id: callStatistics enabled: window.call call: window.call width: container.width relativeTo: callQuality relativeY: CallStyle.header.stats.relativeY onClosed: Logic.handleCallStatisticsClosed() } } ActionButton { icon: 'tel_keypad' onClicked: telKeypad.visible = !telKeypad.visible } ActionButton { id: callSecure icon: window.call && window.call.isSecured ? 'call_chat_secure' : 'call_chat_unsecure' onClicked: zrtp.visible = (window.call.encryption === CallModel.CallEncryptionZrtp) TooltipArea { text: window.call?Logic.makeReadableSecuredString(window.call.securedString):'' } } } // --------------------------------------------------------------------- // Timer. // --------------------------------------------------------------------- Text { id: elapsedTime anchors.fill: parent font.pointSize: CallStyle.header.elapsedTime.fullscreen.pointSize horizontalAlignment: Text.AlignHCenter verticalAlignment: Text.AlignVCenter visible: !window.hideButtons // Not a customizable style. color: 'white' style: Text.Raised styleColor: 'black' Component.onCompleted: { var updateDuration = function () { if(window.caller){ var call = window.caller.call text = Utils.formatElapsedTime(call.duration) Utils.setTimeout(elapsedTime, 1000, updateDuration) } } updateDuration() } } // --------------------------------------------------------------------- // Video actions. // --------------------------------------------------------------------- ActionBar { anchors.right: parent.right iconSize: CallStyle.header.buttonIconSize visible: !hideButtons ActionButton { icon: 'screenshot' onClicked: call.takeSnapshot() TooltipArea { text: qsTr('takeSnapshotLabel') } } ActionSwitch { id: recordingSwitch enabled: call && call.recording icon: 'record' useStates: false visible: SettingsModel.callRecorderEnabled onClicked: !enabled ? call.startRecording() : call.stopRecording() TooltipArea { text: !recordingSwitch.enabled ? qsTr('startRecordingLabel') : qsTr('stopRecordingLabel') } } ActionButton { icon: 'fullscreen' onClicked: window.exit() } } } // ----------------------------------------------------------------------- // Action Buttons. // ----------------------------------------------------------------------- // ------------------------------------------------------------------------- // Zrtp. // ------------------------------------------------------------------------- ZrtpTokenAuthentication { id: zrtp Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter Layout.margins: CallStyle.container.margins call: window.call visible: call && !call.isSecured && call.encryption !== CallModel.CallEncryptionNone z: Constants.zPopup color: CallStyle.backgroundColor } Item { Layout.alignment: Qt.AlignBottom Layout.fillWidth: true Layout.preferredHeight: CallStyle.actionArea.height visible: !hideButtons GridLayout { anchors { left: parent.left leftMargin: CallStyle.actionArea.leftButtonsGroupMargin verticalCenter: parent.verticalCenter } rowSpacing: ActionBarStyle.spacing Row { spacing: CallStyle.actionArea.vu.spacing visible: SettingsModel.muteMicrophoneEnabled VuMeter { Timer { interval: 50 repeat: true running: micro.enabled onTriggered: parent.value = call.microVu } enabled: micro.enabled } ActionSwitch { id: micro enabled: call && !call.microMuted icon: 'micro' iconSize: CallStyle.actionArea.iconSize onClicked: call.microMuted = enabled } } Row { spacing: CallStyle.actionArea.vu.spacing VuMeter { Timer { interval: 50 repeat: true running: speaker.enabled onTriggered: parent.value = call.speakerVu } enabled: speaker.enabled } ActionSwitch { id: speaker enabled: call && !call.speakerMuted icon: 'speaker' iconSize: CallStyle.actionArea.iconSize onClicked: call.speakerMuted = enabled } } ActionSwitch { enabled: true icon: 'camera' iconSize: CallStyle.actionArea.iconSize updating: call && call.updating onClicked: window.exit(function () { call.videoEnabled = false }) } ActionButton { Layout.preferredHeight: CallStyle.actionArea.iconSize Layout.preferredWidth: CallStyle.actionArea.iconSize icon: 'options' iconSize: CallStyle.actionArea.iconSize onClicked: Logic.openMediaParameters(Window.window, window) } } ActionBar { anchors { right: parent.right rightMargin: CallStyle.actionArea.rightButtonsGroupMargin verticalCenter: parent.verticalCenter } iconSize: CallStyle.actionArea.iconSize ActionSwitch { enabled: call && !call.pausedByUser icon: 'pause' updating: call && call.updating visible: SettingsModel.callPauseEnabled onClicked: window.exit(function () { call.pausedByUser = enabled }) } ActionButton { icon: 'hangup' onClicked: window.exit(call.terminate) } } } } } // --------------------------------------------------------------------------- // Preview. // --------------------------------------------------------------------------- Loader { active: { var caller = window.caller return caller && !caller.cameraActivated } sourceComponent: cameraPreview Component { id: cameraPreview Camera { property bool scale: false function xPosition () { return window.width / 2 - width / 2 } function yPosition () { return window.height - height } call: window.call isPreview: true height: CallStyle.actionArea.userVideo.height * (scale ? 2 : 1) width: CallStyle.actionArea.userVideo.width * (scale ? 2 : 1) DragBox { container: window draggable: parent xPosition: parent.xPosition yPosition: parent.yPosition onWheel: parent.scale = wheel.angleDelta.y > 0 } } } } // --------------------------------------------------------------------------- // TelKeypad. // --------------------------------------------------------------------------- TelKeypad { id: telKeypad call: window.call visible: false } } linphone-desktop-4.2.5/linphone-app/ui/views/App/Calls/IncomingCall.qml000066400000000000000000000014451376717241300260200ustar00rootroot00000000000000import QtQuick 2.7 import Common 1.0 import Linphone 1.0 import App.Styles 1.0 // ============================================================================= AbstractStartingCall { ActionBar { anchors.centerIn: parent iconSize: CallStyle.actionArea.iconSize ActionButton { icon: 'video_call_accept' visible: SettingsModel.videoSupported onClicked: call.acceptWithVideo() } ActionButton { icon: 'call_accept' onClicked: call.accept() } } ActionBar { anchors { right: parent.right rightMargin: CallStyle.actionArea.rightButtonsGroupMargin verticalCenter: parent.verticalCenter } iconSize: CallStyle.actionArea.iconSize ActionButton { icon: 'hangup' onClicked: call.terminate() } } } linphone-desktop-4.2.5/linphone-app/ui/views/App/Calls/OutgoingCall.qml000066400000000000000000000022271376717241300260470ustar00rootroot00000000000000import QtQuick 2.7 import QtQuick.Layouts 1.3 import Common 1.0 import Common.Styles 1.0 import App.Styles 1.0 // ============================================================================= AbstractStartingCall { showKeypad:true GridLayout { columns: parent.width < CallStyle.actionArea.lowWidth && call.videoEnabled ? 1 : 2 rowSpacing: ActionBarStyle.spacing anchors { left: parent.left leftMargin: CallStyle.actionArea.leftButtonsGroupMargin verticalCenter: parent.verticalCenter } ActionSwitch { enabled: !call.microMuted icon: 'micro' iconSize: CallStyle.actionArea.iconSize onClicked: call.microMuted = enabled } } Item { anchors.centerIn: parent height: CallStyle.actionArea.userVideo.height width: CallStyle.actionArea.userVideo.width visible: call.videoEnabled } ActionBar { anchors { right: parent.right rightMargin: CallStyle.actionArea.rightButtonsGroupMargin verticalCenter: parent.verticalCenter } iconSize: CallStyle.actionArea.iconSize ActionButton { icon: 'hangup' onClicked: call.terminate() } } } linphone-desktop-4.2.5/linphone-app/ui/views/App/Calls/ZrtpTokenAuthentication.qml000066400000000000000000000055161376717241300303240ustar00rootroot00000000000000import QtQuick 2.7 import QtQuick.Layouts 1.3 import Common 1.0 import App.Styles 1.0 // ============================================================================= Rectangle{ id: zrtp property var call visible: false color:"transparent" implicitWidth: columnLayout.implicitWidth implicitHeight: columnLayout.implicitHeight+CallStyle.container.margins radius: 10 ColumnLayout { id:columnLayout // --------------------------------------------------------------------------- Layout.fillWidth: true anchors.bottom: parent.bottom // --------------------------------------------------------------------------- // Main text. // --------------------------------------------------------------------------- Text { Layout.fillWidth: true horizontalAlignment: Text.AlignHCenter verticalAlignment: Text.AlignVCenter text: qsTr('confirmSas') color: CallStyle.zrtpArea.text.colorA elide: Text.ElideRight font { bold: true pointSize: CallStyle.zrtpArea.text.pointSize } } // --------------------------------------------------------------------------- // Rules. // --------------------------------------------------------------------------- Row { Layout.alignment: Qt.AlignHCenter spacing: CallStyle.zrtpArea.text.wordsSpacing Text { color: CallStyle.zrtpArea.text.colorA font.pointSize: CallStyle.zrtpArea.text.pointSize text: qsTr('codeA') } Text { color: CallStyle.zrtpArea.text.colorB font { bold: true pointSize: CallStyle.zrtpArea.text.pointSize } text: zrtp.call?zrtp.call.localSas:'' } Text { color: CallStyle.zrtpArea.text.colorA font.pointSize: CallStyle.zrtpArea.text.pointSize text: '-' } Text { color: CallStyle.zrtpArea.text.colorA font.pointSize: CallStyle.zrtpArea.text.pointSize text: qsTr('codeB') } Text { color: CallStyle.zrtpArea.text.colorB font { bold: true pointSize: CallStyle.zrtpArea.text.pointSize } text: zrtp.call?zrtp.call.remoteSas:'' } } // --------------------------------------------------------------------------- // Buttons. // --------------------------------------------------------------------------- Row { Layout.alignment: Qt.AlignHCenter spacing: CallStyle.zrtpArea.buttons.spacing TextButtonA { text: qsTr('deny') onClicked: { zrtp.visible = false zrtp.call.verifyAuthenticationToken(false) } } TextButtonB { text: qsTr('accept') onClicked: { zrtp.visible = false zrtp.call.verifyAuthenticationToken(true) } } } } } linphone-desktop-4.2.5/linphone-app/ui/views/App/Main/000077500000000000000000000000001376717241300225705ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/ui/views/App/Main/Assistant.qml000066400000000000000000000042401376717241300252540ustar00rootroot00000000000000import QtQuick 2.7 import QtQuick.Controls 2.2 import QtQuick.Window 2.2 import Utils 1.0 import App.Styles 1.0 // ============================================================================= Item { id: assistant readonly property string viewsPath: 'qrc:/ui/views/App/Main/Assistant/' readonly property alias nViews: stack.depth // --------------------------------------------------------------------------- function pushView (view, properties) { stack.push( Utils.isString(view) ? viewsPath + view + '.qml' : view, properties ) } function getView (index) { return stack.get(index) } function popView () { stack.pop() } // --------------------------------------------------------------------------- Rectangle { anchors.fill: parent color: AssistantStyle.color } // --------------------------------------------------------------------------- StackView { id: stack anchors { fill: parent bottomMargin: AssistantStyle.bottomMargin leftMargin: AssistantStyle.leftMargin rightMargin: AssistantStyle.rightMargin topMargin: AssistantStyle.topMargin } initialItem: assistant.viewsPath + 'AssistantHome.qml' // ------------------------------------------------------------------------- popEnter: Transition { YAnimator { duration: AssistantStyle.stackAnimation.duration easing.type: Easing.OutBack from: stack.height + AssistantStyle.bottomMargin to: 0 } } popExit: Transition { XAnimator { duration: AssistantStyle.stackAnimation.duration easing.type: Easing.OutBack from: 0 to: stack.width + AssistantStyle.rightMargin } } pushEnter: Transition { XAnimator { duration: AssistantStyle.stackAnimation.duration easing.type: Easing.OutBack from: stack.width + AssistantStyle.rightMargin to: 0 } } pushExit: Transition { YAnimator { duration: AssistantStyle.stackAnimation.duration easing.type: Easing.OutBack from: 0 to: stack.height + AssistantStyle.bottomMargin } } } } linphone-desktop-4.2.5/linphone-app/ui/views/App/Main/Assistant/000077500000000000000000000000001376717241300245415ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/ui/views/App/Main/Assistant/ActivateAppSipAccountWithEmail.qml000066400000000000000000000033221376717241300332520ustar00rootroot00000000000000import QtQuick 2.7 import Common 1.0 import Linphone 1.0 import LinphoneUtils 1.0 import App.Styles 1.0 // ============================================================================= AssistantAbstractView { property var assistantModel backEnabled: false title: qsTr('activateAppSipAccount').replace('%1', Qt.application.name.toUpperCase()) mainAction: requestBlock.execute mainActionEnabled: !requestBlock.loading mainActionLabel: qsTr('confirmAction') Column { anchors.centerIn: parent spacing: ActivateAppSipAccountWithEmailStyle.spacing width: parent.width Text { color: ActivateAppSipAccountWithEmailStyle.activationSteps.color font.pointSize: ActivateAppSipAccountWithEmailStyle.activationSteps.pointSize horizontalAlignment: Text.AlignHCenter text: qsTr('activationSteps').replace('%1', assistantModel.email) width: parent.width wrapMode: Text.WordWrap } RequestBlock { id: requestBlock action: assistantModel.activate width: parent.width } } // --------------------------------------------------------------------------- // Assistant. // --------------------------------------------------------------------------- Connections { target: assistantModel onActivateStatusChanged: { requestBlock.stop(error) if (!error.length) { function quitToHome (window) { window.unlockView() window.setView('Home') } var codecInfo = VideoCodecsModel.getCodecInfo('H264') if (codecInfo.downloadUrl) { LinphoneUtils.openCodecOnlineInstallerDialog(window, codecInfo, quitToHome) } else { quitToHome(window) } } } } } ActivateAppSipAccountWithPhoneNumber.qml000066400000000000000000000037711376717241300343760ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/ui/views/App/Main/Assistantimport QtQuick 2.7 import Common 1.0 import Linphone 1.0 import LinphoneUtils 1.0 import App.Styles 1.0 // ============================================================================= AssistantAbstractView { property var assistantModel backEnabled: false title: qsTr('activateAppSipAccount').replace('%1', Qt.application.name.toUpperCase()) mainAction: requestBlock.execute mainActionEnabled: activationCode.length === 4 && !requestBlock.loading mainActionLabel: qsTr('confirmAction') Column { anchors.centerIn: parent spacing: ActivateAppSipAccountWithPhoneNumberStyle.spacing width: parent.width Text { color: ActivateAppSipAccountWithPhoneNumberStyle.activationSteps.color font.pointSize: ActivateAppSipAccountWithPhoneNumberStyle.activationSteps.pointSize horizontalAlignment: Text.AlignHCenter text: qsTr('activationSteps').replace('%1', assistantModel.phoneNumber) width: parent.width wrapMode: Text.WordWrap } TextField { id: activationCode anchors.horizontalCenter: parent.horizontalCenter validator: IntValidator { bottom: 0 top: 9999 } onTextChanged: assistantModel.activationCode = text } RequestBlock { id: requestBlock action: assistantModel.activate width: parent.width } } // --------------------------------------------------------------------------- // Assistant. // --------------------------------------------------------------------------- Connections { target: assistantModel onActivateStatusChanged: { requestBlock.stop(error) if (!error.length) { function quitToHome (window) { window.unlockView() window.setView('Home') } var codecInfo = VideoCodecsModel.getCodecInfo('H264') if (codecInfo.downloadUrl) { LinphoneUtils.openCodecOnlineInstallerDialog(window, codecInfo, quitToHome) } else { quitToHome(window) } } } } } linphone-desktop-4.2.5/linphone-app/ui/views/App/Main/Assistant/AssistantAbstractView.qml000066400000000000000000000050631376717241300315500ustar00rootroot00000000000000import QtQuick 2.7 import QtQuick.Layouts 1.3 import Common 1.0 import App.Styles 1.0 // ============================================================================= Item { id: view // --------------------------------------------------------------------------- property alias mainActionEnabled: mainActionButton.enabled property alias mainActionLabel: mainActionButton.text property var mainAction property alias description: description.text property alias title: title.text property bool backEnabled: true default property alias _content: content.data // --------------------------------------------------------------------------- height: stack.height width: stack.width // --------------------------------------------------------------------------- // Info. // --------------------------------------------------------------------------- Column { anchors.centerIn: parent spacing: AssistantAbstractViewStyle.info.spacing width: parent.width Text { id: title color: AssistantAbstractViewStyle.info.title.color elide: Text.ElideRight font { pointSize: AssistantAbstractViewStyle.info.title.pointSize bold: true } horizontalAlignment: Text.AlignHCenter width: parent.width } Text { id: description color: AssistantAbstractViewStyle.info.description.color elide: Text.ElideRight font.pointSize: AssistantAbstractViewStyle.info.description.pointSize horizontalAlignment: Text.AlignHCenter width: parent.width visible: text.length > 0 } // ------------------------------------------------------------------------- // Content. // ------------------------------------------------------------------------- Item { id: content anchors.horizontalCenter: parent.horizontalCenter height: AssistantAbstractViewStyle.content.height width: AssistantAbstractViewStyle.content.width } } // --------------------------------------------------------------------------- // Nav buttons. // --------------------------------------------------------------------------- Row { id: buttons anchors { bottom: parent.bottom horizontalCenter: parent.horizontalCenter } spacing: AssistantAbstractViewStyle.buttons.spacing TextButtonA { text: qsTr('back') visible: view.backEnabled onClicked: assistant.popView() } TextButtonB { id: mainActionButton visible: !!view.mainAction onClicked: view.mainAction() } } } linphone-desktop-4.2.5/linphone-app/ui/views/App/Main/Assistant/AssistantHome.qml000066400000000000000000000070301376717241300300360ustar00rootroot00000000000000import QtQuick 2.7 import QtQuick.Layouts 1.3 import Common 1.0 import Linphone 1.0 import App.Styles 1.0 // ============================================================================= ColumnLayout { spacing: 0 // --------------------------------------------------------------------------- // Info. // --------------------------------------------------------------------------- Item { Layout.fillHeight: true Layout.fillWidth: true Column { anchors.verticalCenter: parent.verticalCenter spacing: 0 height: AssistantHomeStyle.info.height width: parent.width Icon { anchors.horizontalCenter: parent.horizontalCenter icon: 'home_account_assistant' iconSize: AssistantHomeStyle.info.iconSize } Text { height: AssistantHomeStyle.info.title.height width: parent.width color: AssistantHomeStyle.info.title.color elide: Text.ElideRight horizontalAlignment: Text.AlignHCenter verticalAlignment: Text.AlignVCenter font { bold: true pointSize: AssistantHomeStyle.info.title.pointSize } text: qsTr('homeTitle') } Text { height: AssistantHomeStyle.info.description.height width: parent.width color: AssistantHomeStyle.info.description.color elide: Text.ElideRight font.pointSize: AssistantHomeStyle.info.description.pointSize horizontalAlignment: Text.AlignHCenter verticalAlignment: Text.AlignVCenter text: qsTr('homeDescription') } } } // --------------------------------------------------------------------------- // Buttons. // --------------------------------------------------------------------------- GridView { id: buttons Layout.alignment: Qt.AlignHCenter Layout.fillWidth: true Layout.maximumWidth: AssistantHomeStyle.buttons.maxWidth Layout.preferredHeight: AssistantHomeStyle.buttons.height cellHeight: height / 2 cellWidth: width / 2 delegate: Item { height: buttons.cellHeight width: buttons.cellWidth TextButtonA { anchors { fill: parent margins: AssistantHomeStyle.buttons.spacing } enabled: SettingsModel[$viewType.charAt(0).toLowerCase() + $viewType.slice(1) + "Enabled"] text: $text.replace('%1', Qt.application.name.toUpperCase()) onClicked: assistant.pushView($view) } } model: ListModel { Component.onCompleted: { insert(0, { $text: qsTr('createAppSipAccount'), $view: SettingsModel.assistantSupportsPhoneNumbers ? 'CreateAppSipAccount' : 'CreateAppSipAccountWithEmail', $viewType: 'CreateAppSipAccount' }) } ListElement { $text: qsTr('useAppSipAccount') $view: 'UseAppSipAccount' $viewType: 'UseAppSipAccount' } ListElement { $text: qsTr('useOtherSipAccount') $view: 'UseOtherSipAccount' $viewType: 'UseOtherSipAccount' } ListElement { $text: qsTr('fetchRemoteConfiguration') $view: 'FetchRemoteConfiguration' $viewType: 'FetchRemoteConfiguration' } } interactive: false Connections { target: SettingsModel onAssistantSupportsPhoneNumbersChanged: buttons.model.setProperty( 0, '$view', SettingsModel.assistantSupportsPhoneNumbers ? 'CreateAppSipAccount' : 'CreateAppSipAccountWithEmail' ) } } } linphone-desktop-4.2.5/linphone-app/ui/views/App/Main/Assistant/CreateAppSipAccount.qml000066400000000000000000000021001376717241300311020ustar00rootroot00000000000000import QtQuick 2.7 import Common 1.0 import App.Styles 1.0 // ============================================================================= AssistantAbstractView { description: qsTr('createAppSipAccountDescription') title: qsTr('createAppSipAccountTitle').replace('%1', Qt.application.name.toUpperCase()) // --------------------------------------------------------------------------- // Menu. // --------------------------------------------------------------------------- Column { anchors.centerIn: parent spacing: CreateAppSipAccountStyle.buttons.spacing width: CreateAppSipAccountStyle.buttons.button.width TextButtonA { text: qsTr('withPhoneNumber') height: CreateAppSipAccountStyle.buttons.button.height width: parent.width onClicked: assistant.pushView('CreateAppSipAccountWithPhoneNumber') } TextButtonA { text: qsTr('withEmailAddress') height: CreateAppSipAccountStyle.buttons.button.height width: parent.width onClicked: assistant.pushView('CreateAppSipAccountWithEmail') } } } linphone-desktop-4.2.5/linphone-app/ui/views/App/Main/Assistant/CreateAppSipAccountWithEmail.qml000066400000000000000000000057231376717241300327240ustar00rootroot00000000000000import QtQuick 2.7 import Common 1.0 import Linphone 1.0 import App.Styles 1.0 // ============================================================================= AssistantAbstractView { id: view property alias emailError: email.error property alias passwordError: password.error property alias usernameError: username.error title: qsTr('createAppSipAccountTitle').replace('%1', Qt.application.name.toUpperCase()) mainAction: requestBlock.execute mainActionEnabled: email.text.length && password.text.length && passwordConfirmation.text === password.text && username.text.length && !emailError.length && !passwordError.length && !requestBlock.loading && !usernameError.length mainActionLabel: qsTr('confirmAction') Column { anchors.fill: parent Form { dealWithErrors: true orientation: Qt.Vertical width: parent.width FormLine { FormGroup { label: qsTr('usernameLabel') TextField { id: username onTextChanged: assistantModel.username = text } } FormGroup { label: qsTr('displayNameLabel') TextField { onTextChanged: assistantModel.displayName = text } } } FormLine { FormGroup { label: qsTr('emailLabel') TextField { id: email onTextChanged: assistantModel.email = text } } } FormLine { FormGroup { label: qsTr('passwordLabel') PasswordField { id: password onTextChanged: { assistantModel.password = text assistantModel.checkPassword() } } } } FormLine { FormGroup { label: qsTr('passwordConfirmationLabel') PasswordField { id: passwordConfirmation onTextChanged: assistantModel.checkPassword() } } } } RequestBlock { id: requestBlock action: assistantModel.create width: parent.width } } // --------------------------------------------------------------------------- // Assistant. // --------------------------------------------------------------------------- AssistantModel { id: assistantModel function checkPassword () { passwordConfirmation.error = password.text !== passwordConfirmation.text ? qsTr('passwordConfirmationError') : '' } configFilename: 'create-app-sip-account.rc' onEmailChanged: emailError = error onPasswordChanged: passwordError = error onUsernameChanged: usernameError = error onCreateStatusChanged: { requestBlock.stop(error) if (error.length) { return } window.lockView({ descriptionText: qsTr('quitWarning') }) assistant.pushView('ActivateAppSipAccountWithEmail', { assistantModel: assistantModel }) } } } CreateAppSipAccountWithPhoneNumber.qml000066400000000000000000000056331376717241300340400ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/ui/views/App/Main/Assistantimport QtQuick 2.7 import Common 1.0 import Linphone 1.0 // ============================================================================= AssistantAbstractView { id: view property alias usernameError: username.error property alias phoneNumberError: phoneNumber.error function setCountryCode (index) { var model = country.model assistantModel.countryCode = model.data(model.index(index, 0)).countryCode } title: qsTr('createAppSipAccountTitle').replace('%1', Qt.application.name.toUpperCase()) mainAction: requestBlock.execute mainActionEnabled: phoneNumber.text.length && username.text.length && !phoneNumberError.length && !usernameError.length && !requestBlock.loading mainActionLabel: qsTr('confirmAction') Column { anchors.fill: parent Form { dealWithErrors: true orientation: Qt.Vertical width: parent.width FormLine { FormGroup { label: qsTr('countryLabel') ComboBox { id: country currentIndex: model.defaultIndex model: TelephoneNumbersModel {} textRole: 'countryName' onActivated: { view.setCountryCode(index) var text = phoneNumber.text if (text.length > 0) { assistantModel.phoneNumber = text } } } } } FormLine { FormGroup { label: qsTr('phoneNumberLabel') TextField { id: phoneNumber inputMethodHints: Qt.ImhDialableCharactersOnly onTextChanged: assistantModel.phoneNumber = text } } } FormLine { FormGroup { label: qsTr('usernameLabel') TextField { id: username onTextChanged: assistantModel.username = text } } } FormLine { FormGroup { label: qsTr('displayNameLabel') TextField { onTextChanged: assistantModel.displayName = text } } } } RequestBlock { id: requestBlock action: assistantModel.create width: parent.width } } // --------------------------------------------------------------------------- // Assistant. // --------------------------------------------------------------------------- AssistantModel { id: assistantModel configFilename: 'create-app-sip-account.rc' Component.onCompleted: view.setCountryCode(country.model.defaultIndex) onPhoneNumberChanged: phoneNumberError = error onUsernameChanged: usernameError = error onCreateStatusChanged: { requestBlock.stop(error) if (error.length) { return } window.lockView({ descriptionText: qsTr('quitWarning') }) assistant.pushView('ActivateAppSipAccountWithPhoneNumber', { assistantModel: assistantModel }) } } } linphone-desktop-4.2.5/linphone-app/ui/views/App/Main/Assistant/FetchRemoteConfiguration.qml000066400000000000000000000026761376717241300322240ustar00rootroot00000000000000import QtQuick 2.7 import Common 1.0 import Linphone 1.0 import Utils 1.0 // ============================================================================= AssistantAbstractView { mainAction: requestBlock.execute mainActionEnabled: url.text.length > 0 mainActionLabel: qsTr('confirmAction') title: qsTr('fetchRemoteConfigurationTitle') // --------------------------------------------------------------------------- Connections { target: SettingsModel onRemoteProvisioningChanged: { requestBlock.stop('') window.detachVirtualWindow() window.attachVirtualWindow(Utils.buildDialogUri('ConfirmDialog'), { descriptionText: qsTr('remoteProvisioningUpdateDescription'), }, function (status) { if (status) { App.restart() } else { window.setView('Home') } }) } onRemoteProvisioningNotChanged: requestBlock.stop(qsTr('remoteProvisioningError')) } // --------------------------------------------------------------------------- Column { anchors.fill: parent Form { orientation: Qt.Vertical width: parent.width FormLine { FormGroup { label: qsTr('urlLabel') TextField { id: url } } } } RequestBlock { id: requestBlock action: (function () { SettingsModel.remoteProvisioning = url.text }) width: parent.width } } } linphone-desktop-4.2.5/linphone-app/ui/views/App/Main/Assistant/UseAppSipAccount.qml000066400000000000000000000057701376717241300304530ustar00rootroot00000000000000import QtQuick 2.7 import Common 1.0 import Linphone 1.0 import LinphoneUtils 1.0 import App.Styles 1.0 // ============================================================================= AssistantAbstractView { id: view readonly property bool usePhoneNumber: SettingsModel.assistantSupportsPhoneNumbers && !checkBox.checked mainAction: requestBlock.execute mainActionEnabled: { var item = loader.item return item && item.mainActionEnabled && !requestBlock.loading } mainActionLabel: qsTr('confirmAction') title: qsTr('useAppSipAccountTitle').replace('%1', Qt.application.name.toUpperCase()) // --------------------------------------------------------------------------- Column { anchors.fill: parent Loader { id: loader source: 'UseAppSipAccountWith' + (view.usePhoneNumber ? 'PhoneNumber' : 'Username') + '.qml' width: parent.width } CheckBoxText { id: checkBox text: qsTr('useUsernameToLogin') visible: SettingsModel.assistantSupportsPhoneNumbers width: UseAppSipAccountStyle.checkBox.width onClicked: { assistantModel.reset() requestBlock.stop('') if (!checked) { assistantModel.setCountryCode(telephoneNumbersModel.defaultIndex) } } } RequestBlock { id: requestBlock action: assistantModel.login width: parent.width } } // --------------------------------------------------------------------------- // Assistant. // --------------------------------------------------------------------------- AssistantModel { id: assistantModel function setCountryCode (index) { var model = telephoneNumbersModel assistantModel.countryCode = index !== -1 ? model.data(model.index(index, 0)).countryCode : '' } configFilename: 'use-app-sip-account.rc' countryCode: setCountryCode(view.usePhoneNumber ? telephoneNumbersModel.defaultIndex : -1) onPasswordChanged: { if (!view.usePhoneNumber) { loader.item.passwordError = error } } onPhoneNumberChanged: { if (view.usePhoneNumber) { loader.item.phoneNumberError = error } } onLoginStatusChanged: { requestBlock.stop(error) if (!error.length) { var codecInfo = VideoCodecsModel.getCodecInfo('H264') if (codecInfo.downloadUrl) { LinphoneUtils.openCodecOnlineInstallerDialog(window, codecInfo, function cb (window) { window.setView('Home') }) } else { window.setView('Home') } } } onRecoverStatusChanged: { if (!view.usePhoneNumber) { requestBlock.stop('') return } requestBlock.stop(error) if (!error.length) { window.lockView({ descriptionText: qsTr('quitWarning') }) assistant.pushView('ActivateAppSipAccountWithPhoneNumber', { assistantModel: assistantModel }) } } } TelephoneNumbersModel { id: telephoneNumbersModel } } linphone-desktop-4.2.5/linphone-app/ui/views/App/Main/Assistant/UseAppSipAccountWithPhoneNumber.qml000066400000000000000000000017621376717241300334470ustar00rootroot00000000000000import Common 1.0 import Linphone 1.0 // ============================================================================= Form { property alias phoneNumberError: phoneNumber.error property bool mainActionEnabled: phoneNumber.text.length && !phoneNumberError.length dealWithErrors: true orientation: Qt.Vertical FormLine { FormGroup { label: qsTr('countryLabel') ComboBox { id: country currentIndex: model.defaultIndex model: telephoneNumbersModel textRole: 'countryName' onActivated: { assistantModel.setCountryCode(index) var text = phoneNumber.text if (text.length > 0) { assistantModel.phoneNumber = text } } } } } FormLine { FormGroup { label: qsTr('phoneNumberLabel') TextField { id: phoneNumber inputMethodHints: Qt.ImhDialableCharactersOnly onTextChanged: assistantModel.phoneNumber = text } } } } linphone-desktop-4.2.5/linphone-app/ui/views/App/Main/Assistant/UseAppSipAccountWithUsername.qml000066400000000000000000000013521376717241300327770ustar00rootroot00000000000000import Common 1.0 // ============================================================================= Form { property alias passwordError: password.error property alias usernameError: username.error property bool mainActionEnabled: password.text && username.length && !passwordError.length && !usernameError.length dealWithErrors: true orientation: Qt.Vertical FormLine { FormGroup { label: qsTr('usernameLabel') TextField { id: username onTextChanged: assistantModel.username = text } } } FormLine { FormGroup { label: qsTr('passwordLabel') PasswordField { id: password onTextChanged: assistantModel.password = text } } } } linphone-desktop-4.2.5/linphone-app/ui/views/App/Main/Assistant/UseOtherSipAccount.qml000066400000000000000000000040021376717241300307770ustar00rootroot00000000000000import QtQuick 2.7 import Common 1.0 import Linphone 1.0 // ============================================================================= AssistantAbstractView { mainAction: requestBlock.execute mainActionEnabled: username.text.length && sipDomain.text.length && password.text.length mainActionLabel: qsTr('confirmAction') title: qsTr('useOtherSipAccountTitle') // --------------------------------------------------------------------------- Column { anchors.fill: parent Form { dealWithErrors: true orientation: Qt.Vertical width: parent.width FormLine { FormGroup { label: qsTr('usernameLabel') TextField { id: username } } FormGroup { label: qsTr('displayNameLabel') TextField { id: displayName } } } FormLine { FormGroup { label: qsTr('sipDomainLabel') TextField { id: sipDomain } } } FormLine { FormGroup { label: qsTr('passwordLabel') PasswordField { id: password } } } FormLine { FormGroup { label: qsTr('transportLabel') ComboBox { id: transport model: [ 'UDP', 'TCP', 'TLS'] } } } } RequestBlock { id: requestBlock action: (function () { if (!assistantModel.addOtherSipAccount({ username: username.text, displayName: displayName.text, sipDomain: sipDomain.text, password: password.text, transport: transport.model[transport.currentIndex] })) { requestBlock.stop(qsTr('addOtherSipAccountError')) } else { requestBlock.stop('') window.setView('Home') } }) width: parent.width } } AssistantModel { id: assistantModel configFilename: 'use-other-sip-account.rc' } } linphone-desktop-4.2.5/linphone-app/ui/views/App/Main/ContactEdit.js000066400000000000000000000142331376717241300253320ustar00rootroot00000000000000/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ // ============================================================================= // `Conversation.qml` Logic. // ============================================================================= .import Linphone 1.0 as Linphone .import 'qrc:/ui/scripts/Utils/utils.js' as Utils .import 'qrc:/ui/scripts/LinphoneUtils/linphone-utils.js' as LinphoneUtils // ============================================================================= function handleContactUpdated () { var contact = contactEdit._contact if (!contactEdit._edition) { var vcard = contact.vcard if (contactEdit._vcard !== vcard) { // Not in edition mode, the contact was updated in other place. contactEdit._vcard = vcard } else { // Edition ended. handleVcardChanged(contact.vcard) } } else { // Edition not ended, the contact was updated in other place. // Update fields with new data. contactEdit._vcard = contact.cloneVcardModel() } } function handleCreation () { var sipAddress = contactEdit.sipAddress var contact = contactEdit._contact = Linphone.SipAddressesModel.mapSipAddressToContact( sipAddress ) if (!contact) { // Add a new contact. var vcard = Linphone.CoreManager.createDetachedVcardModel() if (sipAddress && sipAddress.length > 0) { vcard.addSipAddress(sipAddress) vcard.username = LinphoneUtils.getContactUsername(Linphone.SipAddressesModel.getSipAddressObserver(sipAddress, sipAddress)) }else{ vcard.username = ' '// Username initialization to avoid Belr parsing issue when setting new name } contactEdit._vcard = vcard contactEdit._edition = true } else { // See or edit a contact. contactEdit._vcard = contact.vcard } } function handleVcardChanged (vcard) { if (!vcard) { vcard = {} } addresses.setData(vcard.sipAddresses) companies.setData(vcard.companies) emails.setData(vcard.emails) urls.setData(vcard.urls) } // ----------------------------------------------------------------------------- function editContact () { var contact = contactEdit._contact contactEdit._vcard = contact.cloneVcardModel() contactEdit._edition = true window.lockView({ descriptionText: qsTr('abortEditDescriptionText') }) } function removeContact () { window.attachVirtualWindow(Utils.buildDialogUri('ConfirmDialog'), { descriptionText: qsTr('removeContactDescription'), }, function (status) { if (status) { window.unlockView() window.setView('Contacts') Linphone.ContactsListModel.removeContact(_contact) } }) } // ----------------------------------------------------------------------------- function save () { var contact = contactEdit._contact var vcard = contactEdit._vcard contactEdit._edition = false if (contact) { contact.vcard = vcard window.unlockView() } else { contactEdit._contact = Linphone.ContactsListModel.addContact(vcard) handleVcardChanged(vcard) // Called directly, because the vcard is not modified in the view. } } function cancel () { var contact = contactEdit._contact if (contact) { contactEdit._vcard = contact.vcard window.unlockView() contactEdit._edition = false } else { window.setView('Contacts') } } // ----------------------------------------------------------------------------- function setAvatar (url) { contactEdit._vcard.avatar = Utils.getSystemPathFromUri(url) } function setUsername (username) { var vcard = contactEdit._vcard vcard.username = username // Update current text with new/old username. usernameInput.text = _vcard.username } // ----------------------------------------------------------------------------- function handleValueChanged (fields, index, oldValue, newValue, add, update) { if (newValue === oldValue) { return } var vcard = contactEdit._vcard var soFarSoGood = (oldValue.length === 0) ? vcard[add](newValue) : vcard[update](oldValue, newValue) fields.setInvalid(index, !soFarSoGood) } function handleSipAddressChanged () { var args = Array.prototype.slice.call(arguments) args.push('addSipAddress', 'updateSipAddress') handleValueChanged.apply(this, args) } function handleCompanyChanged () { var args = Array.prototype.slice.call(arguments) args.push('addCompany', 'updateCompany') handleValueChanged.apply(this, args) } function handleEmailChanged () { var args = Array.prototype.slice.call(arguments) args.push('addEmail', 'updateEmail') handleValueChanged.apply(this, args) } function handleUrlChanged () { var args = Array.prototype.slice.call(arguments) args.push('addUrl', 'updateUrl') handleValueChanged.apply(this, args) } // ----------------------------------------------------------------------------- function buildAddressFields () { var address = contactEdit._vcard.address return [{ placeholder: qsTr('street'), text: address.street }, { placeholder: qsTr('locality'), text: address.locality }, { placeholder: qsTr('postalCode'), text: address.postalCode }, { placeholder: qsTr('country'), text: address.country }] } function handleAddressChanged (index, value) { var vcard = contactEdit._vcard if (index === 0) { // Street. vcard.setStreet(value) } else if (index === 1) { // Locality. vcard.setLocality(value) } else if (index === 2) { // Postal code. vcard.setPostalCode(value) } else if (index === 3) { // Country. vcard.setCountry(value) } } linphone-desktop-4.2.5/linphone-app/ui/views/App/Main/ContactEdit.qml000066400000000000000000000211051376717241300255030ustar00rootroot00000000000000import QtQuick 2.7 import QtQuick.Controls 2.2 import QtQuick.Dialogs 1.2 import QtQuick.Layouts 1.3 import Common 1.0 import Linphone 1.0 import Linphone.Styles 1.0 import App.Styles 1.0 import 'ContactEdit.js' as Logic // ============================================================================= ColumnLayout { id: contactEdit property string sipAddress readonly property alias vcard: contactEdit._vcard property bool _edition: false property var _contact property var _vcard // --------------------------------------------------------------------------- spacing: 0 Component.onCompleted: Logic.handleCreation() onVcardChanged: Logic.handleVcardChanged(vcard) // --------------------------------------------------------------------------- Loader { active: contactEdit._contact != null sourceComponent: Connections { target: contactEdit._contact onContactUpdated: Logic.handleContactUpdated() } } FileDialog { id: avatarChooser folder: shortcuts.home title: qsTr('avatarChooserTitle') onAccepted: Logic.setAvatar(fileUrls[0]) } // --------------------------------------------------------------------------- // Info bar. // --------------------------------------------------------------------------- Rectangle { id: infoBar Layout.fillWidth: true Layout.preferredHeight: ContactEditStyle.bar.height color: ContactEditStyle.bar.color RowLayout { anchors { fill: parent leftMargin: ContactEditStyle.bar.leftMargin rightMargin: ContactEditStyle.bar.rightMargin } spacing: ContactEditStyle.bar.spacing ActionButton { enabled: _edition icon: 'contact_card_photo' iconSize: ContactEditStyle.bar.avatarSize onClicked: avatarChooser.open() Avatar { id: avatar anchors.fill: parent image: _vcard.avatar username: _vcard.username presenceLevel: _contact ? _contact.presenceLevel : -1 visible: (isLoaded() && !parent.hovered) || !_edition } } TransparentTextInput { id: usernameInput Layout.fillWidth: true Layout.preferredHeight: ContactEditStyle.bar.buttons.size color: ContactEditStyle.bar.username.color font { bold: true pointSize: ContactEditStyle.bar.username.pointSize } forceFocus: true readOnly: !_edition text: avatar.username onEditingFinished: Logic.setUsername(text) onReadOnlyChanged: { if (!readOnly) { forceActiveFocus() } } } Row { Layout.alignment: Qt.AlignRight Layout.fillHeight: true spacing: ContactEditStyle.bar.actions.spacing visible: _contact != null ActionBar { anchors.verticalCenter: parent.verticalCenter iconSize: ContactEditStyle.bar.actions.history.iconSize ActionButton { icon: 'history' onClicked: sipAddressesMenu.open() TooltipArea { text: qsTr('tooltipShowConversation') } } } ActionBar { anchors.verticalCenter: parent.verticalCenter ActionButton { icon: 'edit' iconSize: ContactEditStyle.bar.actions.edit.iconSize visible: !_edition onClicked: Logic.editContact() } ActionButton { icon: 'delete' iconSize: ContactEditStyle.bar.actions.del.iconSize onClicked: Logic.removeContact() } } } } } // --------------------------------------------------------------------------- SipAddressesMenu { id: sipAddressesMenu relativeTo: infoBar relativeX: infoBar.width - SipAddressesMenuStyle.entry.width relativeY: infoBar.height sipAddresses: _contact ? _contact.vcard.sipAddresses : [ contactEdit.sipAddress ] onSipAddressClicked: window.setView('Conversation', { peerAddress: sipAddress, localAddress: AccountSettingsModel.sipAddress, fullPeerAddress: sipAddress, fullLocalAddress: AccountSettingsModel.fullSipAddress }) } // --------------------------------------------------------------------------- // Info list. // --------------------------------------------------------------------------- Rectangle { Layout.fillHeight: true Layout.fillWidth: true color: ContactEditStyle.content.color Flickable { id: flick ScrollBar.vertical: ForceScrollBar {} anchors.fill: parent boundsBehavior: Flickable.StopAtBounds clip: true contentHeight: infoList.height contentWidth: width - ScrollBar.vertical.width flickableDirection: Flickable.VerticalFlick // ----------------------------------------------------------------------- ColumnLayout { id: infoList width: flick.contentWidth ListForm { id: addresses Layout.leftMargin: ContactEditStyle.values.leftMargin Layout.rightMargin: ContactEditStyle.values.rightMargin Layout.topMargin: ContactEditStyle.values.topMargin minValues: _contact ? 1 : 0 placeholder: qsTr('sipAccountsPlaceholder') readOnly: !_edition title: qsTr('sipAccounts') onChanged: Logic.handleSipAddressChanged(addresses, index, oldValue, newValue) onRemoved: _vcard.removeSipAddress(value) } Rectangle { Layout.fillWidth: true Layout.preferredHeight: ContactEditStyle.values.separator.height color: ContactEditStyle.values.separator.color } ListForm { id: companies Layout.leftMargin: ContactEditStyle.values.leftMargin Layout.rightMargin: ContactEditStyle.values.rightMargin placeholder: qsTr('companiesPlaceholder') readOnly: !_edition title: qsTr('companies') onChanged: Logic.handleCompanyChanged(companies, index, oldValue, newValue) onRemoved: _vcard.removeCompany(value) } Rectangle { Layout.fillWidth: true Layout.preferredHeight: ContactEditStyle.values.separator.height color: ContactEditStyle.values.separator.color } ListForm { id: emails Layout.leftMargin: ContactEditStyle.values.leftMargin Layout.rightMargin: ContactEditStyle.values.rightMargin placeholder: qsTr('emailsPlaceholder') readOnly: !_edition title: qsTr('emails') onChanged: Logic.handleEmailChanged(emails, index, oldValue, newValue) onRemoved: _vcard.removeEmail(value) } Rectangle { Layout.fillWidth: true Layout.preferredHeight: ContactEditStyle.values.separator.height color: ContactEditStyle.values.separator.color } ListForm { id: urls Layout.leftMargin: ContactEditStyle.values.leftMargin Layout.rightMargin: ContactEditStyle.values.rightMargin placeholder: qsTr('webSitesPlaceholder') readOnly: !_edition title: qsTr('webSites') onChanged: Logic.handleUrlChanged(urls, index, oldValue, newValue) onRemoved: _vcard.removeUrl(value) } Rectangle { Layout.fillWidth: true Layout.preferredHeight: ContactEditStyle.values.separator.height color: ContactEditStyle.values.separator.color } StaticListForm { Layout.leftMargin: ContactEditStyle.values.leftMargin Layout.rightMargin: ContactEditStyle.values.rightMargin fields: Logic.buildAddressFields() readOnly: !_edition title: qsTr('address') onChanged: Logic.handleAddressChanged(index, value) } // --------------------------------------------------------------------- // Edition buttons. // --------------------------------------------------------------------- Row { Layout.alignment: Qt.AlignHCenter Layout.bottomMargin: ContactEditStyle.values.bottomMargin Layout.topMargin: ContactEditStyle.buttons.topMargin spacing: ContactEditStyle.buttons.spacing visible: _edition TextButtonA { text: qsTr('cancel') onClicked: Logic.cancel() } TextButtonB { enabled: usernameInput.text.length > 0 && _vcard.sipAddresses.length > 0 text: qsTr('save') onClicked: Logic.save() } } } } } } linphone-desktop-4.2.5/linphone-app/ui/views/App/Main/Contacts.qml000066400000000000000000000177111376717241300250700ustar00rootroot00000000000000import QtQuick 2.7 import QtQuick.Layouts 1.3 import Common 1.0 import Linphone 1.0 import Utils 1.0 import App.Styles 1.0 // ============================================================================= ColumnLayout { function _removeContact (contact) { window.attachVirtualWindow(Utils.buildDialogUri('ConfirmDialog'), { descriptionText: qsTr('removeContactDescription'), }, function (status) { if (status) { ContactsListModel.removeContact(contact) } }) } spacing: 0 // --------------------------------------------------------------------------- // Search Bar & actions. // --------------------------------------------------------------------------- Rectangle { Layout.fillWidth: true Layout.preferredHeight: ContactsStyle.bar.height color: ContactsStyle.bar.backgroundColor RowLayout { anchors { fill: parent leftMargin: ContactsStyle.bar.leftMargin rightMargin: ContactsStyle.bar.rightMargin } spacing: ContactsStyle.spacing TextField { Layout.fillWidth: true icon: 'filter' placeholderText: qsTr('searchContactPlaceholder') onTextChanged: contacts.setFilter(text) } ExclusiveButtons { texts: [ qsTr('selectAllContacts'), qsTr('selectConnectedContacts') ] onClicked: contacts.useConnectedFilter = !!button } TextButtonB { text: qsTr('addContact') onClicked: window.setView('ContactEdit') } } } // --------------------------------------------------------------------------- // Contacts list. // --------------------------------------------------------------------------- Rectangle { Layout.fillWidth: true Layout.fillHeight: true color: ContactsStyle.backgroundColor ScrollableListView { anchors.fill: parent spacing: 0 model: ContactsListProxyModel { id: contacts } delegate: Borders { bottomColor: ContactsStyle.contact.border.color bottomWidth: ContactsStyle.contact.border.width height: ContactsStyle.contact.height width: parent ? parent.width : 0 // --------------------------------------------------------------------- Rectangle { id: contact anchors.fill: parent color: ContactsStyle.contact.backgroundColor.normal // ------------------------------------------------------------------- Component { id: container1 RowLayout { spacing: ContactsStyle.contact.spacing PresenceLevel { Layout.preferredHeight: ContactsStyle.contact.presenceLevelSize Layout.preferredWidth: ContactsStyle.contact.presenceLevelSize level: $contact.presenceLevel } Text { Layout.fillWidth: true color: ContactsStyle.contact.presence.color elide: Text.ElideRight font.pointSize: ContactsStyle.contact.presence.pointSize text: Presence.getPresenceStatusAsString($contact.presenceStatus) } } } Component { id: container2 Item { ActionBar { anchors { left: parent.left verticalCenter: parent.verticalCenter } iconSize: ContactsStyle.contact.actionButtonsSize ActionButton { icon: 'video_call' visible: SettingsModel.videoSupported && SettingsModel.outgoingCallsEnabled onClicked: actions.itemAt(0).open() } ActionButton { icon: 'call' visible: SettingsModel.outgoingCallsEnabled onClicked: actions.itemAt(1).open() } ActionButton { icon: SettingsModel.chatEnabled ? 'chat' : 'history' onClicked: actions.itemAt(2).open() } } ActionButton { anchors { right: parent.right verticalCenter: parent.verticalCenter } icon: 'delete' iconSize: ContactsStyle.contact.deleteButtonSize onClicked: _removeContact($contact) } } } // ------------------------------------------------------------------- Repeater { id: actions readonly property var handlers: [ CallsListModel.launchVideoCall, CallsListModel.launchAudioCall, function (sipAddress) { window.setView('Conversation', { peerAddress: sipAddress, localAddress: AccountSettingsModel.sipAddress, fullPeerAddress: sipAddress, fullLocalAddress: AccountSettingsModel.fullSipAddress }) } ] model: handlers SipAddressesMenu { relativeTo: loader relativeY: loader.height sipAddresses: $contact.vcard.sipAddresses onSipAddressClicked: actions.handlers[index](sipAddress) } } // ------------------------------------------------------------------- Rectangle { id: indicator anchors.left: parent.left color: 'transparent' height: parent.height width: ContactsStyle.contact.indicator.width } MouseArea { id: mouseArea anchors.fill: parent cursorShape: Qt.ArrowCursor MouseArea { anchors.fill: parent onClicked: window.setView('ContactEdit', { sipAddress: $contact.vcard.sipAddresses[0] }) } RowLayout { anchors { fill: parent leftMargin: ContactsStyle.contact.leftMargin rightMargin: ContactsStyle.contact.rightMargin } spacing: ContactsStyle.contact.spacing Item { Layout.preferredHeight: parent.height Layout.preferredWidth: parent.height Avatar { anchors.centerIn: parent image: $contact.vcard.avatar username: $contact.vcard.username height: ContactsStyle.contact.avatarSize width: ContactsStyle.contact.avatarSize } } Text { Layout.fillHeight: true Layout.preferredWidth: ContactsStyle.contact.username.width color: ContactsStyle.contact.username.color elide: Text.ElideRight font { bold: true pointSize: ContactsStyle.contact.username.pointSize } text: $contact.vcard.username verticalAlignment: Text.AlignVCenter } // Container. Loader { id: loader Layout.fillWidth: true Layout.fillHeight: true sourceComponent: container1 } } } // ------------------------------------------------------------------- states: State { when: mouseArea.containsMouse PropertyChanges { color: ContactsStyle.contact.backgroundColor.hovered target: contact } PropertyChanges { color: ContactsStyle.contact.indicator.color target: indicator } PropertyChanges { sourceComponent: container2 target: loader } } } } } } } linphone-desktop-4.2.5/linphone-app/ui/views/App/Main/Conversation.js000066400000000000000000000043721376717241300256060ustar00rootroot00000000000000/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ // ============================================================================= // `Conversation.qml` Logic. // ============================================================================= .import Linphone 1.0 as Linphone .import 'qrc:/ui/scripts/LinphoneUtils/linphone-utils.js' as LinphoneUtils .import 'qrc:/ui/scripts/Utils/utils.js' as Utils // ============================================================================= function removeAllEntries () { window.attachVirtualWindow(Utils.buildDialogUri('ConfirmDialog'), { descriptionText: qsTr('removeAllEntriesDescription'), }, function (status) { if (status) { chatProxyModel.removeAllEntries() } }) } function getAvatar () { var contact = conversation._sipAddressObserver.contact return contact ? contact.vcard.avatar : '' } function getEditIcon () { return conversation._sipAddressObserver.contact ? 'contact_edit' : 'contact_add' } function getEditTooltipText() { return conversation._sipAddressObserver.contact ? qsTr('tooltipContactEdit') : qsTr('tooltipContactAdd') } function getUsername () { return LinphoneUtils.getContactUsername(conversation._sipAddressObserver) } function updateChatFilter (button) { var ChatModel = Linphone.ChatModel if (button === 0) { chatProxyModel.setEntryTypeFilter(ChatModel.GenericEntry) } else if (button === 1) { chatProxyModel.setEntryTypeFilter(ChatModel.CallEntry) } else { chatProxyModel.setEntryTypeFilter(ChatModel.MessageEntry) } } linphone-desktop-4.2.5/linphone-app/ui/views/App/Main/Conversation.qml000066400000000000000000000123241376717241300257570ustar00rootroot00000000000000import QtQuick 2.7 import QtQuick.Layouts 1.3 import Common 1.0 import Linphone 1.0 import App.Styles 1.0 import 'Conversation.js' as Logic // ============================================================================= ColumnLayout { id: conversation property string peerAddress property string localAddress property string fullPeerAddress property string fullLocalAddress readonly property var _sipAddressObserver: SipAddressesModel.getSipAddressObserver((fullPeerAddress?fullPeerAddress:peerAddress), (fullLocalAddress?fullLocalAddress:localAddress)) // --------------------------------------------------------------------------- spacing: 0 // --------------------------------------------------------------------------- // Contact bar. // --------------------------------------------------------------------------- Rectangle { Layout.fillWidth: true Layout.preferredHeight: ConversationStyle.bar.height color: ConversationStyle.bar.backgroundColor RowLayout { anchors { fill: parent leftMargin: ConversationStyle.bar.leftMargin rightMargin: ConversationStyle.bar.rightMargin } spacing: ConversationStyle.bar.spacing Avatar { id: avatar Layout.preferredHeight: ConversationStyle.bar.avatarSize Layout.preferredWidth: ConversationStyle.bar.avatarSize image: Logic.getAvatar() presenceLevel: Presence.getPresenceLevel( conversation._sipAddressObserver.presenceStatus ) username: Logic.getUsername() } ContactDescription { Layout.fillHeight: true Layout.fillWidth: true sipAddress: conversation.peerAddress sipAddressColor: ConversationStyle.bar.description.sipAddressColor username: avatar.username usernameColor: ConversationStyle.bar.description.usernameColor } Row { Layout.fillHeight: true spacing: ConversationStyle.bar.actions.spacing ActionBar { anchors.verticalCenter: parent.verticalCenter iconSize: ConversationStyle.bar.actions.call.iconSize ActionButton { icon: 'video_call' visible: SettingsModel.videoSupported && SettingsModel.outgoingCallsEnabled onClicked: CallsListModel.launchVideoCall(conversation.peerAddress) } ActionButton { icon: 'call' visible: SettingsModel.outgoingCallsEnabled onClicked: CallsListModel.launchAudioCall(conversation.peerAddress) } } ActionBar { anchors.verticalCenter: parent.verticalCenter ActionButton { icon: Logic.getEditIcon() iconSize: ConversationStyle.bar.actions.edit.iconSize visible: SettingsModel.contactsEnabled onClicked: window.setView('ContactEdit', { sipAddress: conversation.peerAddress }) TooltipArea { text: Logic.getEditTooltipText() } } ActionButton { icon: 'delete' iconSize: ConversationStyle.bar.actions.edit.iconSize onClicked: Logic.removeAllEntries() TooltipArea { text: qsTr('cleanHistory') } } } } } } // --------------------------------------------------------------------------- // Messages/Calls filters. // --------------------------------------------------------------------------- Borders { Layout.fillWidth: true Layout.preferredHeight: active ? ConversationStyle.filters.height : 0 borderColor: ConversationStyle.filters.border.color bottomWidth: ConversationStyle.filters.border.bottomWidth color: ConversationStyle.filters.backgroundColor topWidth: ConversationStyle.filters.border.topWidth visible: SettingsModel.chatEnabled ExclusiveButtons { anchors { left: parent.left leftMargin: ConversationStyle.filters.leftMargin verticalCenter: parent.verticalCenter } texts: [ qsTr('displayCallsAndMessages'), qsTr('displayCalls'), qsTr('displayMessages') ] onClicked: Logic.updateChatFilter(button) } } // --------------------------------------------------------------------------- // Chat. // --------------------------------------------------------------------------- Chat { Layout.fillHeight: true Layout.fillWidth: true proxyModel: ChatProxyModel { id: chatProxyModel Component.onCompleted: { if (!SettingsModel.chatEnabled) { setEntryTypeFilter(ChatModel.CallEntry) } resetMessageCount() } peerAddress: conversation.peerAddress localAddress: conversation.localAddress fullPeerAddress: conversation.fullPeerAddress fullLocalAddress: conversation.fullLocalAddress } } Connections { target: SettingsModel onChatEnabledChanged: chatProxyModel.setEntryTypeFilter(status ? ChatModel.GenericEntry : ChatModel.CallEntry) } Connections { target: AccountSettingsModel onAccountSettingsUpdated: { if (conversation.localAddress !== AccountSettingsModel.sipAddress) { window.setView('Home') } } } } linphone-desktop-4.2.5/linphone-app/ui/views/App/Main/Dialogs/000077500000000000000000000000001376717241300241525ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/ui/views/App/Main/Dialogs/About.qml000066400000000000000000000046351376717241300257470ustar00rootroot00000000000000import QtQuick 2.7 import QtQuick.Layouts 1.3 import Common 1.0 import Linphone 1.0 import App.Styles 1.0 // ============================================================================= DialogPlus { buttons: [ TextButtonB { text: qsTr('ok') onClicked: exit(0) } ] centeredButtons: true objectName: '__about' height: AboutStyle.height width: AboutStyle.width Column { anchors.fill: parent spacing: AboutStyle.spacing RowLayout { id:versionsLayout spacing: AboutStyle.versionsBlock.spacing height: AboutStyle.versionsBlock.iconSize width: parent.width Icon { icon: 'linphone_logo' iconSize: parent.height } Column { id:versionsArea Layout.fillWidth: true Layout.preferredHeight: parent.height spacing: 0 TextEdit { id: appVersion color: AboutStyle.versionsBlock.appVersion.color selectByMouse: true font.pointSize: AboutStyle.versionsBlock.appVersion.pointSize text: 'Desktop ' + Qt.application.version + ' - Qt' + App.qtVersion +'\nCore ' + CoreManager.version height: parent.height width: parent.width verticalAlignment: Text.AlignVCenter onActiveFocusChanged: deselect(); } } } Column { spacing: AboutStyle.copyrightBlock.spacing width: parent.width Text { elide: Text.ElideRight font.pointSize: AboutStyle.copyrightBlock.url.pointSize linkColor: AboutStyle.copyrightBlock.url.color text: ''+applicationUrl+'' width: parent.width horizontalAlignment: Text.AlignHCenter onLinkActivated: Qt.openUrlExternally(link) MouseArea { anchors.fill: parent acceptedButtons: Qt.NoButton cursorShape: parent.hoveredLink ? Qt.PointingHandCursor : Qt.IBeamCursor } } Text { color: AboutStyle.copyrightBlock.license.color elide: Text.ElideRight font.pointSize: AboutStyle.copyrightBlock.license.pointSize text: 'GNU General Public License V3\n\u00A9 2010-' + (new Date().toLocaleDateString(Qt.locale(), 'yyyy')) + ' Belledonne Communications' width: parent.width horizontalAlignment: Text.AlignHCenter } } } } linphone-desktop-4.2.5/linphone-app/ui/views/App/Main/Dialogs/AuthenticationRequest.js000066400000000000000000000023171376717241300310430ustar00rootroot00000000000000/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ // ============================================================================= // `AuthenticationRequest.qml` Logic. // ============================================================================= .import Linphone 1.0 as Linphone // ============================================================================= function confirmPassword () { Linphone.AccountSettingsModel.addAuthInfo(dialog.authInfo, password.text, userId.text) } linphone-desktop-4.2.5/linphone-app/ui/views/App/Main/Dialogs/AuthenticationRequest.qml000066400000000000000000000030041376717241300312120ustar00rootroot00000000000000import QtQuick 2.7 import Common 1.0 import App.Styles 1.0 import 'AuthenticationRequest.js' as Logic // ============================================================================= DialogPlus { id: dialog property alias realm: realm.text property alias sipAddress: identity.text property alias userId: userId.text property var authInfo buttons: [ TextButtonA { text: qsTr('cancel') onClicked: exit(0) }, TextButtonB { enabled: password.length > 0 text: qsTr('confirm') onClicked: { Logic.confirmPassword() exit(1) } } ] centeredButtons: true descriptionText: qsTr('authenticationRequestDescription') height: AuthenticationRequestStyle.height width: AuthenticationRequestStyle.width // --------------------------------------------------------------------------- Form { anchors.fill: parent orientation: Qt.Vertical FormLine { FormGroup { label: qsTr('identityLabel') TextField { id: identity readOnly: true } } } FormLine { FormGroup { label: qsTr('realmLabel') TextField { id: realm readOnly: true } } } FormLine { FormGroup { label: qsTr('userIdLabel') TextField { id: userId } } } FormLine { FormGroup { label: qsTr('passwordLabel') PasswordField { id: password } } } } } linphone-desktop-4.2.5/linphone-app/ui/views/App/Main/Dialogs/ManageAccount.js000066400000000000000000000024621376717241300272210ustar00rootroot00000000000000/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ // ============================================================================= // `ManageAccount.qml` Logic. // ============================================================================= function getItemIcon (data) { var proxyConfig = data.proxyConfig if (!proxyConfig) { return '' } var description = AccountSettingsModel.getProxyConfigDescription(proxyConfig) return description.registerEnabled && description.registrationState !== AccountSettingsModel.RegistrationStateRegistered ? 'generic_error' : '' } linphone-desktop-4.2.5/linphone-app/ui/views/App/Main/Dialogs/ManageAccounts.qml000066400000000000000000000061651376717241300275650ustar00rootroot00000000000000import QtQuick 2.7 import Common 1.0 import Linphone 1.0 import Utils 1.0 import App.Styles 1.0 import 'ManageAccount.js' as Logic // ============================================================================= DialogPlus { buttons: [ TextButtonB { text: qsTr('ok') onClicked: exit(0) } ] centeredButtons: true objectName: '__manageAccounts' height: SettingsModel.rlsUriEnabled ? ManageAccountsStyle.height : ManageAccountsStyle.heightWithoutPresence width: ManageAccountsStyle.width // --------------------------------------------------------------------------- Form { anchors.fill: parent orientation: Qt.Vertical FormLine { visible: SettingsModel.rlsUriEnabled FormGroup { label: qsTr('selectPresenceLabel') ComboBox { currentIndex: Utils.findIndex(OwnPresenceModel.statuses, function (status) { return status.presenceStatus === OwnPresenceModel.presenceStatus }) model: OwnPresenceModel.statuses iconRole: 'presenceIcon' textRole: 'presenceLabel' onActivated: OwnPresenceModel.presenceStatus = model[index].presenceStatus } } } FormLine { FormGroup { label: qsTr('selectAccountLabel') ScrollableListViewField { width: parent.width height: ManageAccountsStyle.accountSelector.height radius: 0 ScrollableListView { id: view property string textRole: 'sipAddress' // Used by delegate. anchors.fill: parent model: AccountSettingsModel.accounts onModelChanged: currentIndex = Utils.findIndex(AccountSettingsModel.accounts, function (account) { return account.sipAddress === AccountSettingsModel.sipAddress }) delegate: CommonItemDelegate { id: item container: view flattenedModel: modelData itemIcon: ''//Start with no error and let some time before getting status with the below timer width: parent.width Timer{// This timer is used to synchronize registration state by proxy, without having to deal with change signals interval: 1000; running: item.visible; repeat: true onTriggered:itemIcon= Logic.getItemIcon(flattenedModel) } ActionButton { icon: 'options' iconSize: 30 anchors.fill: parent visible:false //TODO handle click and jump to proxy config settings } onClicked: { container.currentIndex = index if(flattenedModel.proxyConfig) AccountSettingsModel.setDefaultProxyConfig(flattenedModel.proxyConfig) else AccountSettingsModel.setDefaultProxyConfig() } MessageCounter { anchors.fill: parent count: flattenedModel.unreadMessageCount+flattenedModel.missedCallCount } } } } } } } } linphone-desktop-4.2.5/linphone-app/ui/views/App/Main/HistoryView.js000066400000000000000000000044131376717241300254240ustar00rootroot00000000000000/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ // ============================================================================= // `Conversation.qml` Logic. // ============================================================================= .import Linphone 1.0 as Linphone .import 'qrc:/ui/scripts/LinphoneUtils/linphone-utils.js' as LinphoneUtils .import 'qrc:/ui/scripts/Utils/utils.js' as Utils // ============================================================================= function removeAllEntries () { window.attachVirtualWindow(Utils.buildDialogUri('ConfirmDialog'), { descriptionText: qsTr('removeAllEntriesDescription'), }, function (status) { if (status) { historyProxyModel.removeAllEntries() } }) } function getAvatar () { var contact = historyView._sipAddressObserver.contact return contact ? contact.vcard.avatar : '' } function getEditIcon () { return historyView._sipAddressObserver && historyView._sipAddressObserver.contact ? 'contact_edit' : 'contact_add' } function getEditTooltipText() { return historyView._sipAddressObserver && historyView._sipAddressObserver.contact ? qsTr('tooltipContactEdit') : qsTr('tooltipContactAdd') } function getUsername () { return LinphoneUtils.getContactUsername(historyView._sipAddressObserver) } function updateHistoryFilter (button) { var HistoryModel = Linphone.HistoryModel if (button === 0) { historyProxyModel.setEntryTypeFilter(HistoryModel.GenericEntry) } else if (button === 1) { historyProxyModel.setEntryTypeFilter(HistoryModel.CallEntry) } } linphone-desktop-4.2.5/linphone-app/ui/views/App/Main/HistoryView.qml000066400000000000000000000100421376717241300255740ustar00rootroot00000000000000import QtQuick 2.7 import QtQuick.Layouts 1.3 import Common 1.0 import Linphone 1.0 import App.Styles 1.0 import 'HistoryView.js' as Logic // ============================================================================= ColumnLayout { id: historyView property string peerAddress property string fullPeerAddress readonly property var _sipAddressObserver: peerAddress?SipAddressesModel.getSipAddressObserver((fullPeerAddress?fullPeerAddress:peerAddress), ''):null // --------------------------------------------------------------------------- spacing: 0 // --------------------------------------------------------------------------- // Contact bar. // --------------------------------------------------------------------------- Rectangle { Layout.fillWidth: true Layout.preferredHeight: peerAddress?HistoryViewStyle.bar.height:HistoryViewStyle.bar.height/2 color: HistoryViewStyle.bar.backgroundColor RowLayout { anchors { fill: parent leftMargin: HistoryViewStyle.bar.leftMargin rightMargin: HistoryViewStyle.bar.rightMargin } spacing: HistoryViewStyle.bar.spacing layoutDirection: peerAddress?Qt.LeftToRight :Qt.RightToLeft Avatar { id: avatar Layout.preferredHeight: HistoryViewStyle.bar.avatarSize Layout.preferredWidth: HistoryViewStyle.bar.avatarSize image: peerAddress?Logic.getAvatar():null presenceLevel: historyView._sipAddressObserver?Presence.getPresenceLevel( historyView._sipAddressObserver.presenceStatus ):null username: peerAddress?Logic.getUsername():null visible:peerAddress } ContactDescription { Layout.fillHeight: true Layout.fillWidth: true sipAddress: historyView.peerAddress sipAddressColor: HistoryViewStyle.bar.description.sipAddressColor username: avatar.username usernameColor: HistoryViewStyle.bar.description.usernameColor visible:peerAddress } Row { Layout.fillHeight: true spacing: HistoryViewStyle.bar.actions.spacing ActionBar { anchors.verticalCenter: parent.verticalCenter iconSize: HistoryViewStyle.bar.actions.call.iconSize ActionButton { icon: 'video_call' visible: peerAddress && SettingsModel.videoSupported && SettingsModel.outgoingCallsEnabled onClicked: CallsListModel.launchVideoCall(historyView.peerAddress) } ActionButton { icon: 'call' visible: peerAddress && SettingsModel.outgoingCallsEnabled onClicked: CallsListModel.launchAudioCall(historyView.peerAddress) } } ActionBar { anchors.verticalCenter: parent.verticalCenter ActionButton { icon: Logic.getEditIcon() iconSize: HistoryViewStyle.bar.actions.edit.iconSize visible: peerAddress && SettingsModel.contactsEnabled onClicked: window.setView('ContactEdit', { sipAddress: historyView.peerAddress }) TooltipArea { text: peerAddress?Logic.getEditTooltipText():'' } } ActionButton { icon: 'delete' iconSize: HistoryViewStyle.bar.actions.edit.iconSize onClicked: Logic.removeAllEntries() TooltipArea { text: qsTr('cleanHistory') } } } } } } // --------------------------------------------------------------------------- // History. // --------------------------------------------------------------------------- History { Layout.fillHeight: true Layout.fillWidth: true onEntryClicked:{ historyView.fullPeerAddress=sipAddress historyView.peerAddress=sipAddress historyProxyModel.resetMessageCount() } proxyModel: HistoryProxyModel { id: historyProxyModel Component.onCompleted: { setEntryTypeFilter() resetMessageCount() } } } } linphone-desktop-4.2.5/linphone-app/ui/views/App/Main/Home.qml000066400000000000000000000046101376717241300241740ustar00rootroot00000000000000import QtQuick 2.7 import Common 1.0 import Linphone 1.0 import Linphone.Styles 1.0 import Utils 1.0 import App.Styles 1.0 // ============================================================================= Rectangle { color: HomeStyle.color // TODO: Remove me when smart tooltip will be available. Component { Item { property var i18n: [ QT_TR_NOOP('showTooltips'), QT_TR_NOOP('howToDescription'), QT_TR_NOOP('howToTitle') ] } } ListView { anchors.horizontalCenter: parent.horizontalCenter boundsBehavior: Flickable.StopAtBounds clip: true orientation: ListView.Horizontal spacing: HomeStyle.spacing height: parent.height width: { var width = CardBlockStyle.width * count + (count - 1) * spacing return parent.width < width ? parent.width : width } model: ListModel { // TODO: Uncomment me when smart tooltip will be available. // ListElement { // $component: 'checkBox' // $componentText: qsTr('showTooltips') // $description: qsTr('howToDescription') // $icon: 'home_use_linphone' // $title: qsTr('howToTitle') // } ListElement { $component: 'button' $componentText: qsTr('inviteButton') $description: qsTr('inviteDescription') $view: 'InviteFriends' $icon: 'home_invite_friends' $title: qsTr('inviteTitle') } ListElement { $component: 'button' $componentText: qsTr('assistantButton') $description: qsTr('accountAssistantDescription') $icon: 'home_account_assistant' $title: qsTr('accountAssistantTitle') $view: 'Assistant' } } delegate: CardBlock { anchors.verticalCenter: parent.verticalCenter description: $description.replace('%1', Utils.capitalizeFirstLetter(Qt.application.name)) icon: $icon title: $title.replace('%1', Qt.application.name.toUpperCase()) Loader { Component { id: button TextButtonB { text: $componentText onClicked: window.setView($view) } } Component { id: checkBox CheckBoxText { text: $componentText } } anchors.horizontalCenter: parent.horizontalCenter sourceComponent: $component === 'button' ? button : checkBox } } } } linphone-desktop-4.2.5/linphone-app/ui/views/App/Main/InviteFriends.qml000066400000000000000000000044171376717241300260620ustar00rootroot00000000000000import QtQuick 2.7 import QtQuick.Layouts 1.3 import Common 1.0 import Linphone 1.0 import Utils 1.0 import App.Styles 1.0 // ============================================================================= Rectangle { color: InviteFriendsStyle.color ColumnLayout { anchors.fill: parent spacing: 0 Item { id: content Layout.fillHeight: true Layout.fillWidth: true Form { anchors.centerIn: parent orientation: Qt.Vertical title: qsTr('inviteFriendsTitle') width: InviteFriendsStyle.width FormLine { FormGroup { label: qsTr('enterEmailLabel') TextField { id: email inputMethodHints: Qt.ImhEmailCharactersOnly width: parent.width } } } FormLine { FormGroup { label: qsTr('messageLabel') TextAreaField { id: message height: InviteFriendsStyle.message.height text: qsTr('defaultMessage') .replace('%1', AccountSettingsModel.username) .replace('%2', Utils.capitalizeFirstLetter(Qt.application.name)) } } } } } // ------------------------------------------------------------------------- // Buttons. // ------------------------------------------------------------------------- Row { id: buttons Layout.alignment: Qt.AlignHCenter Layout.bottomMargin: InviteFriendsStyle.buttons.bottomMargin spacing: InviteFriendsStyle.buttons.spacing TextButtonA { text: qsTr('cancel') onClicked: window.setView('Home') } TextButtonB { enabled: email.length && message.length text: qsTr('confirm') onClicked: { Qt.openUrlExternally( 'mailto:' + encodeURIComponent(email.text) + '?subject=' + encodeURIComponent( qsTr('defaultSubject').replace('%1', Utils.capitalizeFirstLetter(Qt.application.name)) ) + '&body=' + encodeURIComponent( message.text + '\n\n' + qsTr('forcedMessage').replace(/%1/g, CoreManager.downloadUrl) ) ) window.setView('Home') } } } } } linphone-desktop-4.2.5/linphone-app/ui/views/App/Main/MainWindow.js000066400000000000000000000074521376717241300252120ustar00rootroot00000000000000/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ // ============================================================================= // `MainWindow.qml` Logic. // ============================================================================= .import Linphone 1.0 as Linphone .import QtQuick.Window 2.2 as Window .import 'qrc:/ui/scripts/Utils/utils.js' as Utils // ============================================================================= function handleActiveFocusItemChanged (activeFocusItem) { var smartSearchBar = window._smartSearchBar if (activeFocusItem == null && smartSearchBar) { smartSearchBar.closeMenu() } } function handleClosing (close) { if (Linphone.SettingsModel.exitOnClose) { Qt.quit() return } if (Qt.platform.os === 'osx') { close.accepted = false window.showMinimized() } } // ----------------------------------------------------------------------------- function lockView (info) { window._lockedInfo = info } function unlockView () { window._lockedInfo = undefined } function setView (view, props) { function apply (view, props) { Linphone.App.smartShowWindow(window) var item = mainLoader.item updateSelectedEntry(view, props) window._currentView = view item.contentLoader.setSource(view + '.qml', props || {}) } var lockedInfo = window._lockedInfo if (!lockedInfo) { apply(view, props) return } window.attachVirtualWindow(Utils.buildDialogUri('ConfirmDialog'), { descriptionText: lockedInfo.descriptionText, }, function (status) { if (status) { unlockView() apply(view, props) } else { updateSelectedEntry(window._currentView, props) } }) } // ----------------------------------------------------------------------------- function openConferenceManager () { var App = Linphone.App var callsWindow = App.getCallsWindow() App.smartShowWindow(callsWindow) callsWindow.openConferenceManager() } function manageAccounts () { window.attachVirtualWindow(Qt.resolvedUrl('Dialogs/ManageAccounts.qml')) } // ----------------------------------------------------------------------------- function updateSelectedEntry (view, props) { var item = mainLoader.item var menu = item.menu var timeline = item.timeline if (view === 'Home') { item.homeEntry.select() timeline.resetSelectedEntry() } else if (view === 'Contacts') { item.contactsEntry.select() timeline.resetSelectedEntry() } else { menu.resetSelectedEntry() if (view === 'Conversation') { timeline.setSelectedEntry(props.peerAddress, props.localAddress) } else if (view === 'ContactEdit') { timeline.resetSelectedEntry() } } } // ----------------------------------------------------------------------------- function handleAuthenticationRequested (authInfo, realm, sipAddress, userId) { window.attachVirtualWindow(Qt.resolvedUrl('Dialogs/AuthenticationRequest.qml'), { authInfo: authInfo, realm: realm, sipAddress: sipAddress, userId: userId, virtualWindowHash:Qt.md5('Dialogs/AuthenticationRequest.qml'+realm+sipAddress+userId) }) } linphone-desktop-4.2.5/linphone-app/ui/views/App/Main/MainWindow.qml000066400000000000000000000204641376717241300253650ustar00rootroot00000000000000import QtQuick 2.7 import QtQuick.Controls 2.2 import QtQuick.Layouts 1.3 import Qt.labs.platform 1.0 import Common 1.0 import Linphone 1.0 import Utils 1.0 import App.Styles 1.0 import 'MainWindow.js' as Logic // ============================================================================= ApplicationWindow { id: window property string _currentView property var _lockedInfo // --------------------------------------------------------------------------- function lockView (info) { Logic.lockView(info) } function unlockView () { Logic.unlockView() } function setView (view, props) { Logic.setView(view, props) } // --------------------------------------------------------------------------- // Window properties. // --------------------------------------------------------------------------- minimumHeight: MainWindowStyle.minimumHeight minimumWidth: MainWindowStyle.minimumWidth title: Utils.capitalizeFirstLetter(Qt.application.name) // --------------------------------------------------------------------------- onActiveFocusItemChanged: Logic.handleActiveFocusItemChanged(activeFocusItem) onClosing: Logic.handleClosing(close) // --------------------------------------------------------------------------- Connections { target: CoreManager onCoreStarted: mainLoader.active = true } Shortcut { sequence: StandardKey.Close onActivated: window.hide() } // --------------------------------------------------------------------------- Loader { id: mainLoader active: false anchors.fill: parent sourceComponent: ColumnLayout { // Workaround to get these properties in `MainWindow.js`. readonly property alias contactsEntry: contactsEntry readonly property alias contentLoader: contentLoader readonly property alias homeEntry: homeEntry readonly property alias menu: menu readonly property alias timeline: timeline spacing: 0 // ----------------------------------------------------------------------- AuthenticationNotifier { onAuthenticationRequested: Logic.handleAuthenticationRequested(authInfo, realm, sipAddress, userId) } // ----------------------------------------------------------------------- // Toolbar properties. // ----------------------------------------------------------------------- ToolBar { Layout.fillWidth: true Layout.preferredHeight: MainWindowStyle.toolBar.height background: MainWindowStyle.toolBar.background RowLayout { anchors { fill: parent leftMargin: MainWindowStyle.toolBar.leftMargin rightMargin: MainWindowStyle.toolBar.rightMargin } spacing: MainWindowStyle.toolBar.spacing AccountStatus { id: accountStatus Layout.fillHeight: parent.height Layout.preferredWidth: MainWindowStyle.accountStatus.width TooltipArea { text: AccountSettingsModel.sipAddress hoveringCursor: Qt.PointingHandCursor } onClicked: { CoreManager.forceRefreshRegisters() Logic.manageAccounts() } } Column { Layout.preferredWidth: MainWindowStyle.autoAnswerStatus.width Icon { icon: SettingsModel.autoAnswerStatus ? 'auto_answer' : '' iconSize: MainWindowStyle.autoAnswerStatus.iconSize } Text { clip: true color: MainWindowStyle.autoAnswerStatus.text.color font { bold: true pointSize: MainWindowStyle.autoAnswerStatus.text.pointSize } text: qsTr('autoAnswerStatus') visible: SettingsModel.autoAnswerStatus width: parent.width } } SmartSearchBar { id: smartSearchBar Layout.fillWidth: true maxMenuHeight: MainWindowStyle.searchBox.maxHeight placeholderText: qsTr('mainSearchBarPlaceholder') tooltipText: qsTr('smartSearchBarTooltip') onAddContact: window.setView('ContactEdit', { sipAddress: sipAddress }) onEntryClicked: { if (entry.contact && SettingsModel.contactsEnabled) { window.setView('ContactEdit', { sipAddress: entry.sipAddress }) } else { window.setView('Conversation', { peerAddress: entry.sipAddress, localAddress: AccountSettingsModel.sipAddress, fullPeerAddress: entry.fullSipAddress, fullLocalAddress: AccountSettingsModel.fullSipAddress }) } } onLaunchCall: CallsListModel.launchAudioCall(sipAddress) onLaunchChat: window.setView('Conversation', { peerAddress: sipAddress, localAddress: AccountSettingsModel.sipAddress, fullPeerAddress: sipAddress, fullLocalAddress: AccountSettingsModel.fullSipAddress }) onLaunchVideoCall: CallsListModel.launchVideoCall(sipAddress) } ActionButton { icon: 'new_conference' iconSize: MainWindowStyle.newConferenceSize visible: SettingsModel.conferenceEnabled onClicked: Logic.openConferenceManager() TooltipArea { text: qsTr('newConferenceButton') } } ActionButton { icon: 'burger_menu' iconSize: MainWindowStyle.menuBurgerSize visible: Qt.platform.os !== 'osx' onClicked: menuBar.open() MainWindowMenuBar { id: menuBar } } } } Loader{ active:Qt.platform.os === 'osx' sourceComponent:MainWindowTopMenuBar{} } // ----------------------------------------------------------------------- // Content. // ----------------------------------------------------------------------- RowLayout { Layout.fillHeight: true Layout.fillWidth: true spacing: 0 // Main menu. ColumnLayout { Layout.maximumWidth: MainWindowStyle.menu.width Layout.preferredWidth: MainWindowStyle.menu.width spacing: 0 ApplicationMenu { id: menu defaultSelectedEntry: homeEntry entryHeight: MainWindowStyle.menu.height entryWidth: MainWindowStyle.menu.width ApplicationMenuEntry { id: homeEntry icon: 'home' name: qsTr('homeEntry') onSelected: setView('Home') } ApplicationMenuEntry { id: contactsEntry icon: 'contact' name: qsTr('contactsEntry') visible: SettingsModel.contactsEnabled onSelected: setView('Contacts') } } // History. Timeline { id: timeline Layout.fillHeight: true Layout.fillWidth: true model: TimelineModel onEntrySelected: (entry?setView('Conversation', { peerAddress: entry, localAddress: AccountSettingsModel.sipAddress, fullPeerAddress: entry, fullLocalAddress: AccountSettingsModel.fullSipAddress }): setView('HistoryView', {}) ) } } // Main content. Loader { id: contentLoader objectName: '__contentLoader' Layout.fillHeight: true Layout.fillWidth: true source: 'Home.qml' } } } } // --------------------------------------------------------------------------- // Url handlers. // --------------------------------------------------------------------------- Connections { target: UrlHandlers onSip: window.setView('Conversation', { peerAddress: sipAddress, localAddress: AccountSettingsModel.sipAddress, fullPeerAddress: sipAddress, fullLocalAddress: AccountSettingsModel.fullSipAddress }) } } linphone-desktop-4.2.5/linphone-app/ui/views/App/Main/MainWindowMenuBar.qml000066400000000000000000000025751376717241300266420ustar00rootroot00000000000000import QtQuick 2.7 import QtQuick.Controls 2.3 import Qt.labs.platform 1.0 import Linphone 1.0 // ============================================================================= Item { function open () { menu.open() } // --------------------------------------------------------------------------- // Shortcuts. // --------------------------------------------------------------------------- Shortcut { id: settingsShortcut sequence: 'Ctrl+P' onActivated: App.smartShowWindow(App.getSettingsWindow()) } Shortcut { id: quitShortcut context: Qt.ApplicationShortcut sequence: StandardKey.Quit onActivated: Qt.quit() } Shortcut { id: aboutShortcut sequence: StandardKey.HelpContents onActivated: { window.detachVirtualWindow() window.attachVirtualWindow(Qt.resolvedUrl('Dialogs/About.qml')) } } // --------------------------------------------------------------------------- // Menu. // --------------------------------------------------------------------------- Menu { id: menu title: qsTr('settings') MenuItem { text: qsTr('settings') onTriggered: settingsShortcut.onActivated() } MenuItem { text: qsTr('about') onTriggered: aboutShortcut.onActivated() } MenuItem { text: qsTr('quit') onTriggered: quitShortcut.onActivated() } } } linphone-desktop-4.2.5/linphone-app/ui/views/App/Main/MainWindowTopMenuBar.qml000066400000000000000000000026001376717241300273120ustar00rootroot00000000000000import QtQuick 2.7 import QtQuick.Controls 2.3 import Qt.labs.platform 1.0 import Linphone 1.0 // ============================================================================= MenuBar { function open () { menu.open() } // --------------------------------------------------------------------------- // Shortcuts. // --------------------------------------------------------------------------- Shortcut { id: settingsShortcut sequence: 'Ctrl+P' onActivated: App.smartShowWindow(App.getSettingsWindow()) } Shortcut { id: quitShortcut context: Qt.ApplicationShortcut sequence: StandardKey.Quit onActivated: Qt.quit() } Shortcut { id: aboutShortcut sequence: StandardKey.HelpContents onActivated: { window.detachVirtualWindow() window.attachVirtualWindow(Qt.resolvedUrl('Dialogs/About.qml')) } } // --------------------------------------------------------------------------- // Menu. // --------------------------------------------------------------------------- Menu { id: menu title: qsTr('settings') MenuItem { text: qsTr('settings') onTriggered: settingsShortcut.onActivated() } MenuItem { text: qsTr('about') onTriggered: aboutShortcut.onActivated() } MenuItem { text: qsTr('quit') onTriggered: quitShortcut.onActivated() } } } linphone-desktop-4.2.5/linphone-app/ui/views/App/Settings/000077500000000000000000000000001376717241300235045ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/ui/views/App/Settings/Dialogs/000077500000000000000000000000001376717241300250665ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/ui/views/App/Settings/Dialogs/SettingsSipAccountsEdit.js000066400000000000000000000106771376717241300322210ustar00rootroot00000000000000/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ // ============================================================================= // `SettingsSipAccounts.qml` Logic. // ============================================================================= .import Linphone 1.0 as Linphone .import 'qrc:/ui/scripts/Utils/utils.js' as Utils // ============================================================================= var proxyConfig function initForm (account) { var AccountSettingsModel = Linphone.AccountSettingsModel proxyConfig = account ? account.proxyConfig : AccountSettingsModel.createProxyConfig() var config = AccountSettingsModel.getProxyConfigDescription(proxyConfig) sipAddress.text = config.sipAddress serverAddress.text = config.serverAddress registrationDuration.text = config.registrationDuration var currentTransport = config.transport.toUpperCase() transport.currentIndex = Number( Utils.findIndex(transport.model, function (value) { return value === currentTransport }) ) route.text = config.route contactParams.text = config.contactParams avpfInterval.text = config.avpfInterval registerEnabled.checked = config.registerEnabled publishPresence.checked = config.publishPresence avpfEnabled.checked = config.avpfEnabled iceEnabled.checked = config.iceEnabled turnEnabled.checked = config.turnEnabled stunServer.text = config.stunServer turnPassword.text = config.turnPassword turnUser.text = config.turnUser if (account) { dialog._sipAddressOk = true dialog._serverAddressOk = true } dialog._routeOk = true } function formIsValid () { return dialog._sipAddressOk && dialog._serverAddressOk && dialog._routeOk } // ----------------------------------------------------------------------------- function validProxyConfig () { if (Linphone.AccountSettingsModel.addOrUpdateProxyConfig(proxyConfig, { sipAddress: sipAddress.text, serverAddress: serverAddress.text, registrationDuration: registrationDuration.text, transport: transport.currentText, route: route.text, contactParams: contactParams.text, avpfInterval: avpfInterval.text, registerEnabled: registerEnabled.checked, publishPresence: publishPresence.checked, avpfEnabled: avpfEnabled.checked, iceEnabled: iceEnabled.checked, turnEnabled: turnEnabled.checked, stunServer: stunServer.text, turnUser: turnUser.text, turnPassword: turnPassword.text })) { dialog.exit(1) } else { // TODO: Display errors on the form (if necessary). } } // ----------------------------------------------------------------------------- function handleRouteChanged (route) { dialog._routeOk = route.length === 0 || Linphone.SipAddressesModel.addressIsValid(route) } function handleServerAddressChanged (address) { if (address.length === 0) { dialog._serverAddressOk = false return } var newTransport = Linphone.SipAddressesModel.getTransportFromSipAddress(address) if (newTransport.length > 0) { transport.currentIndex = Utils.findIndex(transport.model, function (value) { return value === newTransport }) dialog._serverAddressOk = true } else { dialog._serverAddressOk = false } } function handleSipAddressChanged (address) { dialog._sipAddressOk = address.length > 0 && Linphone.SipAddressesModel.sipAddressIsValid(address) } function handleTransportChanged (transport) { var newServerAddress = Linphone.SipAddressesModel.addTransportToSipAddress(serverAddress.text, transport) if (newServerAddress.length > 0) { serverAddress.text = newServerAddress dialog._serverAddressOk = true } else { dialog._serverAddressOk = false } } // ----------------------------------------------------------------------------- linphone-desktop-4.2.5/linphone-app/ui/views/App/Settings/Dialogs/SettingsSipAccountsEdit.qml000066400000000000000000000136351376717241300323730ustar00rootroot00000000000000import QtQuick 2.7 import Common 1.0 import App.Styles 1.0 import 'SettingsSipAccountsEdit.js' as Logic // ============================================================================= DialogPlus { id: dialog property var account // Optional. property bool _sipAddressOk: false property bool _serverAddressOk: false property bool _routeOk: false buttons: [ TextButtonA { text: qsTr('cancel') onClicked: exit(0) }, TextButtonB { enabled: Logic.formIsValid() text: qsTr('confirm') onClicked: Logic.validProxyConfig() } ] centeredButtons: true height: SettingsSipAccountsEditStyle.height width: SettingsSipAccountsEditStyle.width // --------------------------------------------------------------------------- Component.onCompleted: Logic.initForm(account) // --------------------------------------------------------------------------- TabContainer { anchors.fill: parent Column { width: parent.width Form { title: qsTr('mainSipAccountSettingsTitle') width: parent.width FormLine { FormGroup { label: qsTr('sipAddressLabel') + '*' TextField { id: sipAddress placeholderText: 'sip:name@sip.example.net' error: dialog._sipAddressOk ? '' : qsTr('invalidSipAddress') onTextChanged: Logic.handleSipAddressChanged(text) Keys.onReturnPressed: nextItemInFocusChain().forceActiveFocus() } } } FormLine { FormGroup { label: qsTr('serverAddressLabel') + '*' TextField { id: serverAddress placeholderText: 'sip:sip.example.net' error: dialog._serverAddressOk ? '' : qsTr('invalidServerAddress') onActiveFocusChanged: if(!activeFocus && dialog._serverAddressOk) Logic.handleTransportChanged(transport.model[transport.currentIndex]) onTextChanged: Logic.handleServerAddressChanged(text) Keys.onReturnPressed: nextItemInFocusChain().forceActiveFocus() } } } FormLine { FormGroup { label: qsTr('registrationDurationLabel') NumericField { id: registrationDuration Keys.onReturnPressed: route.forceActiveFocus() } } } FormLine { FormGroup { label: qsTr('transportLabel') ComboBox { id: transport enabled: dialog._serverAddressOk model: [ 'UDP', 'TCP', 'TLS' ] onActivated: Logic.handleTransportChanged(model[index]) } } } FormLine { FormGroup { label: qsTr('routeLabel') TextField { id: route error: dialog._routeOk ? '' : qsTr('invalidRoute') onTextChanged: Logic.handleRouteChanged(text) Keys.onReturnPressed: nextItemInFocusChain().forceActiveFocus() } } } FormLine { FormGroup { label: qsTr('contactParamsLabel') TextField { id: contactParams Keys.onReturnPressed: nextItemInFocusChain().forceActiveFocus() } } } FormLine { FormGroup { label: qsTr('avpfIntervalLabel') NumericField { id: avpfInterval maxValue: 5 minValue: 1 Keys.onReturnPressed: focus=false } } } FormLine { FormGroup { label: qsTr('registerEnabledLabel') Switch { id: registerEnabled onClicked: checked = !checked } } } FormLine { FormGroup { label: qsTr('publishPresenceLabel') Switch { id: publishPresence onClicked: checked = !checked } } } FormLine { FormGroup { label: qsTr('avpfEnabledLabel') Switch { id: avpfEnabled onClicked: checked = !checked } } } } // ----------------------------------------------------------------------- // NAT and Firewall. // ----------------------------------------------------------------------- Form { title: qsTr('natAndFirewallTitle') width: parent.width FormLine { FormGroup { label: qsTr('enableIceLabel') Switch { id: iceEnabled onClicked: checked = !checked } } FormGroup { label: qsTr('stunServerLabel') TextField { id: stunServer placeholderText: 'stun.example.net' readOnly: !iceEnabled.checked Keys.onReturnPressed: nextItemInFocusChain().forceActiveFocus() } } } FormLine { FormGroup { label: qsTr('enableTurnLabel') Switch { id: turnEnabled enabled: iceEnabled.checked onClicked: checked = !checked } } FormGroup { label: qsTr('turnUserLabel') TextField { id: turnUser readOnly: !turnEnabled.checked || !turnEnabled.enabled Keys.onReturnPressed: nextItemInFocusChain().forceActiveFocus() } } } FormLine { FormGroup {} FormGroup { label: qsTr('turnPasswordLabel') TextField { id: turnPassword readOnly: !turnEnabled.checked || !turnEnabled.enabled || !turnUser.text.length } } } } } } } linphone-desktop-4.2.5/linphone-app/ui/views/App/Settings/Dialogs/SettingsVideoPreview.qml000066400000000000000000000010171376717241300317310ustar00rootroot00000000000000import QtQuick 2.7 import Common 1.0 import Linphone 1.0 import App.Styles 1.0 // ============================================================================= DialogPlus { id: dialog buttons: [ TextButtonB { text: qsTr('confirm') onClicked: exit(1) } ] centeredButtons: true height: SettingsVideoPreviewStyle.height width: SettingsVideoPreviewStyle.width // --------------------------------------------------------------------------- CameraPreview { anchors.fill: parent } } linphone-desktop-4.2.5/linphone-app/ui/views/App/Settings/SettingsAdvanced.js000066400000000000000000000036221376717241300272730ustar00rootroot00000000000000/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ // ============================================================================= // `SettingsAdvanced.qml` Logic. // ============================================================================= .import Linphone 1.0 as Linphone .import 'qrc:/ui/scripts/Utils/utils.js' as Utils // ============================================================================= function cleanLogs () { window.attachVirtualWindow(Utils.buildDialogUri('ConfirmDialog'), { descriptionText: qsTr('cleanLogsDescription'), }, function (status) { if (status) { Linphone.CoreManager.cleanLogs() } }) } function handleLogsUploaded (url) { if (url.length && Utils.startsWith(url, 'http')) { if(Qt.openUrlExternally( 'mailto:' + encodeURIComponent(Linphone.SettingsModel.logsEmail) + '?subject=' + encodeURIComponent('Desktop Linphone Log') + '&body=' + encodeURIComponent(url) )) sendLogsBlock.stop(qsTr('logsMailerSuccess').replace('%1', url)) else sendLogsBlock.stop(qsTr('logsMailerFailed').replace('%1', url)) } else { sendLogsBlock.stop(qsTr('logsUploadFailed')) } } linphone-desktop-4.2.5/linphone-app/ui/views/App/Settings/SettingsAdvanced.qml000066400000000000000000000051241376717241300274470ustar00rootroot00000000000000import QtQuick 2.7 import Common 1.0 import Linphone 1.0 import App.Styles 1.0 import 'SettingsAdvanced.js' as Logic // ============================================================================= TabContainer { Column { spacing: SettingsWindowStyle.forms.spacing width: parent.width // ------------------------------------------------------------------------- // Logs. // ------------------------------------------------------------------------- Form { title: qsTr('logsTitle') width: parent.width FormLine { FormGroup { label: qsTr('logsFolderLabel') FileChooserButton { selectedFile: SettingsModel.logsFolder selectFolder: true onAccepted: SettingsModel.logsFolder = selectedFile } } } FormLine { FormGroup { label: qsTr('logsUploadUrlLabel') TextField { readOnly: true text: SettingsModel.logsUploadUrl onEditingFinished: SettingsModel.logsUploadUrl = text } } } FormLine { FormGroup { label: qsTr('logsEnabledLabel') Switch { checked: SettingsModel.logsEnabled onClicked: SettingsModel.logsEnabled = !checked } } } FormEmptyLine {} } Row { anchors.right: parent.right spacing: SettingsAdvancedStyle.buttons.spacing TextButtonB { text: qsTr('cleanLogs') onClicked: Logic.cleanLogs() } TextButtonB { enabled: !sendLogsBlock.loading && SettingsModel.logsEnabled text: qsTr('sendLogs') onClicked: sendLogsBlock.execute() } } RequestBlock { id: sendLogsBlock action: CoreManager.sendLogs width: parent.width Connections { target: CoreManager onLogsUploaded: Logic.handleLogsUploaded(url) } } onVisibleChanged: sendLogsBlock.setText('') // ------------------------------------------------------------------------- // Developer settings. // ------------------------------------------------------------------------- Form { title: qsTr('developerSettingsTitle') visible: SettingsModel.developerSettingsEnabled width: parent.width FormLine { FormGroup { label: qsTr('developerSettingsEnabledLabel') Switch { checked: SettingsModel.developerSettingsEnabled onClicked: SettingsModel.developerSettingsEnabled = !checked } } } } } } linphone-desktop-4.2.5/linphone-app/ui/views/App/Settings/SettingsAudio.qml000066400000000000000000000153121376717241300270030ustar00rootroot00000000000000import QtQuick 2.7 as Core import QtQuick.Controls 2.7 as Core import QtQuick.Layouts 1.10 as Core import Common 1.0 import Linphone 1.0 import Utils 1.0 import App.Styles 1.0 // ============================================================================= TabContainer { Core.Column { spacing: SettingsWindowStyle.forms.spacing width: parent.width // ------------------------------------------------------------------------- // Audio parameters. // ------------------------------------------------------------------------- Form { title: qsTr('audioTitle') width: parent.width //Warning if in call FormLine { visible: SettingsModel.isInCall FormGroup { Core.RowLayout { spacing: SettingsAudioStyle.warningMessage.iconSize Icon { icon: 'warning' iconSize: SettingsAudioStyle.warningMessage.iconSize anchors { rightMargin: SettingsAudioStyle.warningMessage.iconSize leftMargin: SettingsAudioStyle.warningMessage.iconSize } } Core.Text { text: qsTr('audioSettingsInCallWarning') } } } } FormLine { FormGroup { label: qsTr('playbackDeviceLabel') ComboBox { currentIndex: Utils.findIndex(model, function (device) { return device === SettingsModel.playbackDevice }) model: SettingsModel.playbackDevices onActivated: SettingsModel.playbackDevice = model[index] } } } FormLine { FormGroup { label: qsTr('playbackGainLabel') enabled: !SettingsModel.isInCall Slider { id: playbackSlider width: parent.width enabled: !SettingsModel.isInCall Core.Component.onCompleted: value = SettingsModel.playbackGain onPositionChanged: SettingsModel.playbackGain = position Core.ToolTip { parent: playbackSlider.handle visible: playbackSlider.pressed text: (playbackSlider.value * 100).toFixed(0) + " %" } } } } FormLine { FormGroup { label: qsTr('captureDeviceLabel') ComboBox { currentIndex: Utils.findIndex(model, function (device) { return device === SettingsModel.captureDevice }) model: SettingsModel.captureDevices onActivated: SettingsModel.captureDevice = model[index] } } } FormLine { FormGroup { label: qsTr('captureGainLabel') Slider { id: captureSlider width: parent.width enabled: !SettingsModel.isInCall Core.Component.onCompleted: value = SettingsModel.captureGain onPositionChanged: SettingsModel.captureGain = position Core.ToolTip { parent: captureSlider.handle visible: captureSlider.pressed text: (captureSlider.value * 100).toFixed(0) + " %" } } } } FormLine { FormGroup { id: audioTestRow label: qsTr('audioTestLabel') visible: !SettingsModel.isInCall Core.Slider { id: audioTestSlider enabled: false width: parent.width anchors { leftMargin: SettingsAudioStyle.ringPlayer.leftMargin } background: Core.Rectangle { x: audioTestSlider.leftPadding y: audioTestSlider.topPadding + audioTestSlider.availableHeight / 2 - height / 2 implicitWidth: 200 implicitHeight: 8 width: audioTestSlider.availableWidth height: implicitHeight radius: 2 color: "#bdbebf" Core.Rectangle { width: audioTestSlider.visualPosition * parent.width height: parent.height color: audioTestSlider.value > 0.8 ? "#ff0000" : "#21be2b" radius: 2 } } //Empty slider handle handle: Core.Text { text: '' visible: false } Core.Timer { interval: 50 repeat: true running: SettingsModel.captureGraphRunning onTriggered: parent.value = SettingsModel.getMicVolume() } } } } FormLine { FormGroup { label: qsTr('ringerDeviceLabel') ComboBox { enabled: !SettingsModel.isInCall currentIndex: Utils.findIndex(model, function (device) { return device === SettingsModel.ringerDevice }) model: SettingsModel.playbackDevices onActivated: SettingsModel.ringerDevice = model[index] } } } FormLine { FormGroup { label: qsTr('ringLabel') FileChooserButton { selectedFile: SettingsModel.ringPath onAccepted: { var item = ringPlayer.item if (item) { item.stop() } SettingsModel.ringPath = selectedFile } ActionSwitch { anchors { left: parent.right leftMargin: SettingsAudioStyle.ringPlayer.leftMargin } enabled: { var item = ringPlayer.item return item && item.playbackState === SoundPlayer.PlayingState } icon: 'pause' onClicked: { var item = ringPlayer.item if (!item) { return } if (enabled) { item.stop() } else { item.play() } } Core.Loader { id: ringPlayer active: window.visible sourceComponent: SoundPlayer { source: SettingsModel.ringPath } } } } } } FormLine { FormGroup { label: qsTr('echoCancellationLabel') Switch { checked: SettingsModel.echoCancellationEnabled onClicked: SettingsModel.echoCancellationEnabled = !checked } } } } // ------------------------------------------------------------------------- // Audio Codecs. // ------------------------------------------------------------------------- Form { title: qsTr('audioCodecsTitle') visible: SettingsModel.showAudioCodecs || SettingsModel.developerSettingsEnabled width: parent.width FormLine { visible: SettingsModel.developerSettingsEnabled FormGroup { label: qsTr('showAudioCodecsLabel') Switch { checked: SettingsModel.showAudioCodecs onClicked: SettingsModel.showAudioCodecs = !checked } } } CodecsViewer { model: AudioCodecsModel width: parent.width } } } } linphone-desktop-4.2.5/linphone-app/ui/views/App/Settings/SettingsCallsChat.qml000066400000000000000000000173061376717241300276050ustar00rootroot00000000000000import QtQuick 2.7 import Common 1.0 import Linphone 1.0 import Utils 1.0 import App.Styles 1.0 // ============================================================================= TabContainer { Column { anchors.fill: parent spacing: SettingsWindowStyle.forms.spacing Form { title: qsTr('callsTitle') width: parent.width FormLine { visible: !!encryption.encryptions.length FormGroup { label: qsTr('encryptionLabel') ExclusiveButtons { id: encryption property var encryptions: (function () { var encryptions = SettingsModel.supportedMediaEncryptions if (encryptions.length) { encryptions.unshift([ SettingsModel.MediaEncryptionNone, qsTr('noEncryption') ]) } return encryptions })() texts: encryptions.map(function (value) { return value[1] }) onClicked: SettingsModel.mediaEncryption = encryptions[button][0] Binding { property: 'selectedButton' target: encryption value: { var toFound = SettingsModel.mediaEncryption return Number( Utils.findIndex(encryption.encryptions, function (value) { return toFound === value[0] }) ) } } } } FormGroup { label: qsTr('encryptionMandatoryLabel') Switch { id: encryptionMandatory checked: SettingsModel.mediaEncryptionMandatory onClicked: SettingsModel.mediaEncryptionMandatory = !checked } } } FormLine { FormGroup { label: qsTr('autoAnswerLabel') Switch { id: autoAnswer checked: SettingsModel.autoAnswerStatus onClicked: SettingsModel.autoAnswerStatus = !checked } } FormGroup { label: qsTr('autoAnswerDelayLabel') NumericField { readOnly: !autoAnswer.checked minValue: 0 maxValue: 30000 step: 1000 text: SettingsModel.autoAnswerDelay onEditingFinished: SettingsModel.autoAnswerDelay = text } } } FormLine { FormGroup { label: qsTr('autoAnswerWithVideoLabel') visible: SettingsModel.videoSupported Switch { checked: SettingsModel.autoAnswerVideoStatus enabled: autoAnswer.checked onClicked: SettingsModel.autoAnswerVideoStatus = !checked } } } FormLine { FormGroup { label: qsTr('showTelKeypadAutomaticallyLabel') Switch { checked: SettingsModel.showTelKeypadAutomatically onClicked: SettingsModel.showTelKeypadAutomatically = !checked } } FormGroup { label: qsTr('keepCallsWindowInBackgroundLabel') Switch { checked: SettingsModel.keepCallsWindowInBackground onClicked: SettingsModel.keepCallsWindowInBackground = !checked } } } FormLine { visible: SettingsModel.developerSettingsEnabled FormGroup { label: qsTr('outgoingCallsEnabledLabel') Switch { checked: SettingsModel.outgoingCallsEnabled onClicked: SettingsModel.outgoingCallsEnabled = !checked } } } FormLine { visible: SettingsModel.developerSettingsEnabled FormGroup { label: qsTr('callRecorderEnabledLabel') Switch { checked: SettingsModel.callRecorderEnabled onClicked: SettingsModel.callRecorderEnabled = !checked } } FormGroup { label: qsTr('callPauseEnabledLabel') Switch { checked: SettingsModel.callPauseEnabled onClicked: SettingsModel.callPauseEnabled = !checked } } } FormLine { visible: SettingsModel.developerSettingsEnabled FormGroup { label: qsTr('muteMicrophoneEnabledLabel') Switch { checked: SettingsModel.muteMicrophoneEnabled onClicked: SettingsModel.muteMicrophoneEnabled = !checked } } } FormLine { visible: SettingsModel.callRecorderEnabled || SettingsModel.developerSettingsEnabled FormGroup { label: qsTr('automaticallyRecordCallsLabel') Switch { checked: SettingsModel.automaticallyRecordCalls onClicked: SettingsModel.automaticallyRecordCalls = !checked } } } } Form { title: qsTr('chatTitle') visible: SettingsModel.chatEnabled || SettingsModel.developerSettingsEnabled width: parent.width FormLine { visible: SettingsModel.developerSettingsEnabled FormGroup { label: qsTr('chatEnabledLabel') Switch { checked: SettingsModel.chatEnabled onClicked: SettingsModel.chatEnabled = !checked } } FormGroup { label: qsTr('conferenceEnabledLabel') Switch { checked: SettingsModel.conferenceEnabled onClicked: SettingsModel.conferenceEnabled = !checked } } } FormLine { FormGroup { label: qsTr('chatNotificationSoundEnabledLabel') Switch { id: enableChatNotificationSound checked: SettingsModel.chatNotificationSoundEnabled onClicked: SettingsModel.chatNotificationSoundEnabled = !checked } } FormGroup { label: qsTr('chatNotificationSoundLabel') FileChooserButton { readOnly: !enableChatNotificationSound.checked selectedFile: SettingsModel.chatNotificationSoundPath onAccepted: SettingsModel.chatNotificationSoundPath = selectedFile } } } FormLine { FormGroup { label: qsTr('fileServerLabel') TextField { text: SettingsModel.fileTransferUrl onEditingFinished: SettingsModel.fileTransferUrl = text } } } FormLine { visible: false // TODO: Use `SettingsModel.limeIsSupported` binding in V2. FormGroup { label: qsTr('encryptWithLimeLabel') ExclusiveButtons { id: lime property var limeStates: ([ [ SettingsModel.LimeStateDisabled, qsTr('limeDisabled') ], [ SettingsModel.LimeStateMandatory, qsTr('limeRequired') ], [ SettingsModel.LimeStatePreferred, qsTr('limePreferred') ] ]) texts: limeStates.map(function (value) { return value[1] }) onClicked: SettingsModel.limeState = limeStates[button][0] Binding { property: 'selectedButton' target: lime value: { var toFound = SettingsModel.limeState return Number( Utils.findIndex(lime.limeStates, function (value) { return toFound === value[0] }) ) } } } } } } Form { title: qsTr('contactsTitle') visible: SettingsModel.developerSettingsEnabled width: parent.width FormLine { FormGroup { label: qsTr('contactsEnabledLabel') Switch { checked: SettingsModel.contactsEnabled onClicked: SettingsModel.contactsEnabled = !checked } } } } } } linphone-desktop-4.2.5/linphone-app/ui/views/App/Settings/SettingsNetwork.qml000066400000000000000000000233531376717241300273770ustar00rootroot00000000000000import QtQuick 2.7 import Common 1.0 import Linphone 1.0 import App.Styles 1.0 // ============================================================================= TabContainer { Column { spacing: SettingsWindowStyle.forms.spacing width: parent.width // ------------------------------------------------------------------------- // General. // ------------------------------------------------------------------------- Form { title: qsTr('generalTitle') visible: SettingsModel.developerSettingsEnabled width: parent.width FormLine { FormGroup { label: qsTr('showNetworkSettingsLabel') Switch { checked: SettingsModel.showNetworkSettings onClicked: SettingsModel.showNetworkSettings = !checked } } } } // ------------------------------------------------------------------------- // Transport. // ------------------------------------------------------------------------- Form { title: qsTr('transportTitle') width: parent.width FormLine { FormGroup { label: qsTr('sendDtmfsLabel') ExclusiveButtons { selectedButton: Number(!SettingsModel.useSipInfoForDtmfs) texts: [ 'SIP INFO', 'RFC 2833' ] onClicked: SettingsModel.useSipInfoForDtmfs = !button } } FormGroup { label: qsTr('allowIpV6Label') Switch { checked: SettingsModel.ipv6Enabled onClicked: SettingsModel.ipv6Enabled = !checked } } } } // ------------------------------------------------------------------------- // Bandwidth control. // ------------------------------------------------------------------------- Form { title: qsTr('bandwidthControlTitle') width: parent.width FormLine { FormGroup { label: qsTr('downloadSpeedLimitLabel') NumericField { minValue: 0 maxValue: 100000 step: 100 text: SettingsModel.downloadBandwidth onEditingFinished: SettingsModel.downloadBandwidth = text } } FormGroup { label: qsTr('uploadSpeedLimitLabel') NumericField { minValue: 0 maxValue: 100000 step: 100 text: SettingsModel.uploadBandwidth onEditingFinished: SettingsModel.uploadBandwidth = text } } } FormLine { FormGroup { label: qsTr('enableAdaptiveRateControlLabel') Switch { checked: SettingsModel.adaptiveRateControlEnabled onClicked: SettingsModel.adaptiveRateControlEnabled = !checked } } } } // ------------------------------------------------------------------------- // Presence. // ------------------------------------------------------------------------- Form { title: qsTr('presenceTitle') width: parent.width FormLine { FormGroup { label: qsTr('rlsUriLabel') ExclusiveButtons { selectedButton: Number(!SettingsModel.rlsUriEnabled) texts: [ qsTr('rlsUriAuto'), qsTr('rlsUriDisabled') ] onClicked: SettingsModel.rlsUriEnabled = !button } } } } // ------------------------------------------------------------------------- // Network protocol and ports. // ------------------------------------------------------------------------- Form { title: qsTr('networkProtocolAndPortsTitle') width: parent.width FormTable { titles: [] FormTableLine { title: qsTr('sipUdpPortLabel') FormTableEntry { width:fixSipUdpPort.width Switch { id: fixSipUdpPort readonly property int defaultPort: 5060 checked: SettingsModel.udpPort > 0 onClicked: SettingsModel.udpPort = (checked ? -2 : defaultPort) } } FormTableEntry { NumericField { minValue: 1 maxValue: 65535 readOnly: !fixSipUdpPort.checked visible:fixSipUdpPort.checked text: SettingsModel.udpPort onEditingFinished: SettingsModel.udpPort = text } } } FormTableLine { title: qsTr('sipTcpPortLabel') FormTableEntry { width:fixSipTcpPort.width Switch { id: fixSipTcpPort readonly property int defaultPort: 5060 checked: SettingsModel.tcpPort > 0 onClicked: SettingsModel.tcpPort = (checked ? -2 : defaultPort) } } FormTableEntry { NumericField { minValue: 1 maxValue: 65535 readOnly: !fixSipTcpPort.checked visible:fixSipTcpPort.checked text: SettingsModel.tcpPort onEditingFinished: SettingsModel.tcpPort = text } } } FormTableLine { id: audioRtpUdpPort readonly property int defaultPort: 7078 title: qsTr('audioRtpUdpPortLabel') FormTableEntry { width:randomAudioRtpUdpPort.width Switch { id: randomAudioRtpUdpPort checked: SettingsModel.audioPortRange[0] !== -1 onClicked: SettingsModel.audioPortRange = checked ? [ -1, -1 ] : [ audioRtpUdpPort.defaultPort, -1 ] } } FormTableEntry { PortField { readOnly: !randomAudioRtpUdpPort.checked visible: randomAudioRtpUdpPort.checked supportsRange: true text: SettingsModel.audioPortRange.join(':') onEditingFinished: SettingsModel.audioPortRange = [ portA, portB ] } } } FormTableLine { id: videoRtpUdpPort readonly property int defaultPort: 9078 title: qsTr('videoRtpUdpPortLabel') visible: SettingsModel.videoSupported FormTableEntry { width:randomVideoRtpUdpPort.width Switch { id: randomVideoRtpUdpPort checked: SettingsModel.videoPortRange[0] !== -1 onClicked: SettingsModel.videoPortRange = checked ? [ -1, -1 ] : [ videoRtpUdpPort.defaultPort, -1 ] } } FormTableEntry { PortField { readOnly: !randomVideoRtpUdpPort.checked visible: randomVideoRtpUdpPort.checked supportsRange: true text: SettingsModel.videoPortRange.join(':') onEditingFinished: SettingsModel.videoPortRange = [ portA, portB ] } } } } } // ------------------------------------------------------------------------- // NAT and Firewall. // ------------------------------------------------------------------------- Form { title: qsTr('natAndFirewallTitle') width: parent.width FormLine { FormGroup { label: qsTr('enableIceLabel') Switch { id: enableIce checked: SettingsModel.iceEnabled onClicked: SettingsModel.iceEnabled = !checked } } FormGroup { label: qsTr('stunServerLabel') TextField { readOnly: !enableIce.checked text: SettingsModel.stunServer onEditingFinished: SettingsModel.stunServer = text } } } FormLine { FormGroup { label: qsTr('enableTurnLabel') Switch { id: enableTurn enabled: enableIce.checked checked: SettingsModel.turnEnabled onClicked: SettingsModel.turnEnabled = !checked } } FormGroup { label: qsTr('turnUserLabel') TextField { id: turnUser readOnly: !enableTurn.checked || !enableTurn.enabled text: SettingsModel.turnUser onEditingFinished: SettingsModel.turnUser = text } } } FormLine { FormGroup {} FormGroup { label: qsTr('turnPasswordLabel') TextField { readOnly: !enableTurn.checked || !enableTurn.enabled || !turnUser.text.length text: SettingsModel.turnPassword onEditingFinished: SettingsModel.turnPassword = text } } } } // ------------------------------------------------------------------------- // DSCP fields. // ------------------------------------------------------------------------- Form { title: qsTr('dscpFieldsTitle') width: parent.width FormLine { FormGroup { label: qsTr('sipFieldLabel') HexField { text: SettingsModel.dscpSip onEditingFinished: SettingsModel.dscpSip = value } } FormGroup {} } FormLine { FormGroup { label: qsTr('audioRtpStreamFieldLabel') HexField { text: SettingsModel.dscpAudio onEditingFinished: SettingsModel.dscpAudio = value } } FormGroup { label: qsTr('videoRtpStreamFieldLabel') visible: SettingsModel.videoSupported HexField { text: SettingsModel.dscpVideo onEditingFinished: SettingsModel.dscpVideo = value } } } } } } linphone-desktop-4.2.5/linphone-app/ui/views/App/Settings/SettingsSipAccounts.js000066400000000000000000000035201376717241300300160ustar00rootroot00000000000000/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ // ============================================================================= // `SettingsSipAccounts.qml` Logic. // ============================================================================= .import Linphone 1.0 as Linphone .import 'qrc:/ui/scripts/Utils/utils.js' as Utils // ============================================================================= function editAccount (account) { window.attachVirtualWindow(Qt.resolvedUrl('Dialogs/SettingsSipAccountsEdit.qml'), { account: account }) } function deleteAccount (account) { window.attachVirtualWindow(Utils.buildDialogUri('ConfirmDialog'), { descriptionText: qsTr('deleteAccountDescription'), }, function (status) { if (status) { Linphone.AccountSettingsModel.removeProxyConfig(account.proxyConfig) } }) } function eraseAllPasswords () { window.attachVirtualWindow(Utils.buildDialogUri('ConfirmDialog'), { descriptionText: qsTr('eraseAllPasswordsDescription'), }, function (status) { if (status) { Linphone.AccountSettingsModel.eraseAllPasswords() } }) } linphone-desktop-4.2.5/linphone-app/ui/views/App/Settings/SettingsSipAccounts.qml000066400000000000000000000107041376717241300301750ustar00rootroot00000000000000import QtQuick 2.7 import QtQuick.Layouts 1.3 import Common 1.0 import Linphone 1.0 import App.Styles 1.0 import 'SettingsSipAccounts.js' as Logic // ============================================================================= TabContainer { Column { spacing: SettingsWindowStyle.forms.spacing width: parent.width // ------------------------------------------------------------------------- // Default identity. // ------------------------------------------------------------------------- Form { title: qsTr('defaultIdentityTitle') width: parent.width FormLine { FormGroup { label: qsTr('defaultDisplayNameLabel') TextField { text: AccountSettingsModel.primaryDisplayName onEditingFinished: AccountSettingsModel.primaryDisplayName = text } } } FormLine { FormGroup { label: qsTr('defaultUsernameLabel') TextField { text: AccountSettingsModel.primaryUsername onEditingFinished: AccountSettingsModel.primaryUsername = text } } } FormLine { FormGroup { label: qsTr('defaultSipAddressLabel') TextField { readOnly: true text: AccountSettingsModel.primarySipAddress } } } } // ------------------------------------------------------------------------- // Proxy accounts. // ------------------------------------------------------------------------- Form { title: qsTr('proxyAccountsTitle') width: parent.width FormTable { legendLineWidth: SettingsWindowStyle.sipAccounts.legendLineWidth titles: [ qsTr('editHeader'), qsTr('deleteHeader') ] Repeater { model: AccountSettingsModel.accounts.slice(1) delegate: FormTableLine { title: modelData.sipAddress FormTableEntry { ActionButton { icon: 'edit' iconSize: SettingsWindowStyle.sipAccounts.iconSize onClicked: Logic.editAccount(modelData) } } FormTableEntry { ActionButton { icon: 'delete' iconSize: SettingsWindowStyle.sipAccounts.iconSize onClicked: Logic.deleteAccount(modelData) } } } } } FormEmptyLine {} } Row { anchors.right: parent.right spacing: SettingsWindowStyle.sipAccounts.buttonsSpacing TextButtonB { text: qsTr('eraseAllPasswords') onClicked: Logic.eraseAllPasswords() } TextButtonB { text: qsTr('addAccount') onClicked: Logic.editAccount() } } // ------------------------------------------------------------------------- // Assistant. // ------------------------------------------------------------------------- Form { title: qsTr('assistantTitle') visible: SettingsModel.developerSettingsEnabled width: parent.width FormLine { FormGroup { label: qsTr('createAppSipAccountEnabledLabel') Switch { checked: SettingsModel.createAppSipAccountEnabled onClicked: SettingsModel.createAppSipAccountEnabled = !checked } } FormGroup { label: qsTr('useAppSipAccountEnabledLabel') Switch { checked: SettingsModel.useAppSipAccountEnabled onClicked: SettingsModel.useAppSipAccountEnabled = !checked } } } FormLine { FormGroup { label: qsTr('useOtherSipAccountEnabledLabel') Switch { checked: SettingsModel.useOtherSipAccountEnabled onClicked: SettingsModel.useOtherSipAccountEnabled = !checked } } FormGroup { label: qsTr('fetchRemoteConfigurationEnabledLabel') Switch { checked: SettingsModel.fetchRemoteConfigurationEnabled onClicked: SettingsModel.fetchRemoteConfigurationEnabled = !checked } } } FormLine { FormGroup { label: qsTr('assistantSupportsPhoneNumbersLabel') Switch { checked: SettingsModel.assistantSupportsPhoneNumbers onClicked: SettingsModel.assistantSupportsPhoneNumbers = !checked } } } } } } linphone-desktop-4.2.5/linphone-app/ui/views/App/Settings/SettingsUi.js000066400000000000000000000040421376717241300261400ustar00rootroot00000000000000/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ // ============================================================================= // `SettingsUi.qml` Logic. // ============================================================================= .import Linphone 1.0 as Linphone .import 'qrc:/ui/scripts/Utils/utils.js' as Utils // ============================================================================= function cleanAvatars () { window.attachVirtualWindow(Utils.buildDialogUri('ConfirmDialog'), { descriptionText: qsTr('cleanAvatarsDescription'), }, function (status) { if (status) { Linphone.ContactsListModel.cleanAvatars() } }) } function getAvailableLocales () { var locales = [] Linphone.App.availableLocales.forEach(function (locale) { locales.push({ key: Utils.capitalizeFirstLetter(locale.nativeLanguageName), value: locale.name }) }) return [{ key: qsTr('systemLocale'), value: '' }].concat(locales.sort(function (a, b) { return a > b })) } function setLocale (locale) { var App = Linphone.App App.configLocale = locale window.detachVirtualWindow() window.attachVirtualWindow(Utils.buildDialogUri('ConfirmDialog'), { descriptionText: qsTr('setLocaleDescription'), }, function (status) { if (status) { App.restart() } }) } linphone-desktop-4.2.5/linphone-app/ui/views/App/Settings/SettingsUi.qml000066400000000000000000000077631376717241300263320ustar00rootroot00000000000000import QtQuick 2.7 import Common 1.0 import Linphone 1.0 import Utils 1.0 import App.Styles 1.0 import 'SettingsUi.js' as Logic // ============================================================================= TabContainer { Column { spacing: SettingsWindowStyle.forms.spacing width: parent.width // ------------------------------------------------------------------------- // Languages. // ------------------------------------------------------------------------- Form { title: qsTr('languagesTitle') width: parent.width FormLine { FormGroup { label: qsTr('languagesLabel') ComboBox { textRole: 'key' Component.onCompleted: { var locales = Logic.getAvailableLocales() model = locales var locale = App.configLocale if (!locale.length) { currentIndex = 0 return } var value = Qt.locale(locale).name currentIndex = Number(Utils.findIndex(locales, function (locale) { return locale.value === value })) } onActivated: Logic.setLocale(model[index].value) } } } } // ------------------------------------------------------------------------- // Paths. // ------------------------------------------------------------------------- Form { title: qsTr('pathsTitle') visible: SettingsModel.videoSupported || SettingsModel.callRecorderEnabled || SettingsModel.chatEnabled || SettingsModel.developerSettingsEnabled width: parent.width FormLine { visible: SettingsModel.videoSupported FormGroup { label: qsTr('savedScreenshotsLabel') FileChooserButton { selectedFile: SettingsModel.savedScreenshotsFolder selectFolder: true onAccepted: SettingsModel.savedScreenshotsFolder = selectedFile } } } FormLine { visible: SettingsModel.callRecorderEnabled || SettingsModel.developerSettingsEnabled FormGroup { label: qsTr('savedCallsLabel') FileChooserButton { selectedFile: SettingsModel.savedCallsFolder selectFolder: true onAccepted: SettingsModel.savedCallsFolder = selectedFile } } } FormLine { visible: SettingsModel.chatEnabled || SettingsModel.developerSettingsEnabled FormGroup { label: qsTr('downloadLabel') FileChooserButton { selectedFile: SettingsModel.downloadFolder selectFolder: true onAccepted: SettingsModel.downloadFolder = selectedFile } } } } // ------------------------------------------------------------------------- // Data. // ------------------------------------------------------------------------- Form { title: qsTr('dataTitle') visible: SettingsModel.contactsEnabled || SettingsModel.developerSettingsEnabled width: parent.width } TextButtonB { anchors.right: parent.right text: qsTr('cleanAvatars') visible: SettingsModel.contactsEnabled || SettingsModel.developerSettingsEnabled onClicked: Logic.cleanAvatars() } // ------------------------------------------------------------------------- // Other. // ------------------------------------------------------------------------- Form { title: qsTr('otherTitle') width: parent.width FormLine { FormGroup { label: qsTr('exitOnCloseLabel') Switch { checked: SettingsModel.exitOnClose onClicked: SettingsModel.exitOnClose = !checked } } FormGroup { label: qsTr('autoStartLabel') Switch { checked: App.autoStart onClicked: App.autoStart = !checked } } } } } } linphone-desktop-4.2.5/linphone-app/ui/views/App/Settings/SettingsVideo.js000066400000000000000000000033031376717241300266300ustar00rootroot00000000000000/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ // ============================================================================= // `SettingsVideo.qml` Logic. // ============================================================================= .import Linphone 1.0 as Linphone .import 'qrc:/ui/scripts/LinphoneUtils/linphone-utils.js' as LinphoneUtils // ============================================================================= function showVideoPreview (account) { window.attachVirtualWindow(Qt.resolvedUrl('Dialogs/SettingsVideoPreview.qml')) } function updateVideoPreview () { var count = Linphone.CallsListModel.rowCount() if (count === 0) { showCameraPreview.enabled = true } else if (count === 1) { showCameraPreview.enabled = false window.detachVirtualWindow() } } function hideVideoPreview () { window.detachVirtualWindow() } function handleCodecDownloadRequested (codecInfo) { LinphoneUtils.openCodecOnlineInstallerDialog(window, codecInfo) } linphone-desktop-4.2.5/linphone-app/ui/views/App/Settings/SettingsVideo.qml000066400000000000000000000114471376717241300270150ustar00rootroot00000000000000import QtQuick 2.7 import QtQuick.Layouts 1.3 import Common 1.0 import Linphone 1.0 import Utils 1.0 import App.Styles 1.0 import 'SettingsVideo.js' as Logic // ============================================================================= TabContainer { Column { spacing: SettingsWindowStyle.forms.spacing width: parent.width // ------------------------------------------------------------------------- // Video parameters. // ------------------------------------------------------------------------- Form { title: qsTr('videoCaptureTitle') width: parent.width //Warning if in call FormLine { visible: SettingsModel.isInCall FormGroup { RowLayout { spacing: SettingsWindowStyle.video.warningMessage.iconSize Icon { icon: 'warning' iconSize: SettingsWindowStyle.video.warningMessage.iconSize anchors { rightMargin: SettingsWindowStyle.video.warningMessage.iconSize leftMargin: SettingsWindowStyle.video.warningMessage.iconSize } } Text { text: qsTr('videoSettingsInCallWarning') } } } } FormLine { FormGroup { label: qsTr('videoInputDeviceLabel') ComboBox { currentIndex: Number(Utils.findIndex(model, function (device) { return device === SettingsModel.videoDevice })) // Number cast => Index is null if app does not support video. model: SettingsModel.videoDevices onActivated: SettingsModel.videoDevice = model[index] } } } FormLine { FormGroup { label: qsTr('videoPresetLabel') ComboBox { currentIndex: { var preset = SettingsModel.videoPreset return Number(Utils.findIndex(model, function (value) { return preset === value.value })) } model: [{ key: qsTr('presetDefault'), value: 'default' }, { key: qsTr('presetHighFps'), value: 'high-fps' }, { key: qsTr('presetCustom'), value: 'custom' }] textRole: 'key' onActivated: SettingsModel.videoPreset = model[index].value } } } FormLine { FormGroup { label: qsTr('videoSizeLabel') ComboBox { currentIndex: Number(Utils.findIndex(model, function (definition) { return definition.value.name === SettingsModel.videoDefinition.name })) // Number cast => Index is null if app does not support video. model: SettingsModel.supportedVideoDefinitions.map(function (definition) { return { key: definition.name + ' (' + definition.width + 'x' + definition.height + ')', value: definition } }) textRole: 'key' onActivated: SettingsModel.videoDefinition = model[index].value } } FormGroup { label: qsTr('videoFramerateLabel') visible: SettingsModel.videoPreset === 'custom' NumericField { maxValue: 60 minValue: 1 text: SettingsModel.videoFramerate onEditingFinished: SettingsModel.videoFramerate = text } } } FormEmptyLine {} } TextButtonB { id: showCameraPreview anchors.right: parent.right enabled: CallsListModel.rowCount() === 0 text: qsTr('showCameraPreview') onClicked: Logic.showVideoPreview() Connections { target: CallsListModel onRowsInserted: Logic.updateVideoPreview() onRowsRemoved: Logic.updateVideoPreview() } Connections { target: window onClosing: Logic.hideVideoPreview() } } // ------------------------------------------------------------------------- // Video Codecs. // ------------------------------------------------------------------------- Form { title: qsTr('videoCodecsTitle') visible: SettingsModel.showVideoCodecs || SettingsModel.developerSettingsEnabled width: parent.width FormLine { visible: SettingsModel.developerSettingsEnabled FormGroup { label: qsTr('showVideoCodecsLabel') Switch { checked: SettingsModel.showVideoCodecs onClicked: SettingsModel.showVideoCodecs = !checked } } } CodecsViewer { model: VideoCodecsModel width: parent.width onDownloadRequested: Logic.handleCodecDownloadRequested(codecInfo) } } } } linphone-desktop-4.2.5/linphone-app/ui/views/App/Settings/SettingsWindow.qml000066400000000000000000000102771376717241300272160ustar00rootroot00000000000000import QtQuick 2.7 import QtQuick.Controls 2.2 import QtQuick.Layouts 1.3 import Common 1.0 import Common.Styles 1.0 import Konami 1.0 import Linphone 1.0 import App.Styles 1.0 // ============================================================================= ApplicationWindow { id: window minimumHeight: SettingsWindowStyle.height minimumWidth: SettingsWindowStyle.width title: qsTr('settingsTitle') onClosing: SettingsModel.settingsWindowClosing() // --------------------------------------------------------------------------- Shortcut { sequence: StandardKey.Close onActivated: window.hide() } // --------------------------------------------------------------------------- Rectangle { anchors.fill: parent color: SettingsWindowStyle.color } ColumnLayout { anchors.fill: parent spacing: 0 // ------------------------------------------------------------------------- // Navigation bar. // ------------------------------------------------------------------------- RowLayout { Layout.fillWidth: true spacing: 0 TabBar { id: tabBar onCurrentIndexChanged: SettingsModel.onSettingsTabChanged(currentIndex) TabButton { iconName: 'settings_sip_accounts' text: qsTr('sipAccountsTab') width: implicitWidth //onClicked: SettingsModel.settingsButtonClicked("sip") } TabButton { iconName: 'settings_audio' text: qsTr('audioTab') width: implicitWidth //onClicked: SettingsModel.accessAudioSettings() //onClicked: SettingsModel.settingsButtonClicked("audio") } TabButton { enabled: SettingsModel.videoSupported iconName: 'settings_video' text: qsTr('videoTab') width: implicitWidth //onClicked: SettingsModel.accessVideoSettings() //onClicked: SettingsModel.settingsButtonClicked("video") } TabButton { iconName: 'settings_call' text: qsTr('callsAndChatTab') width: implicitWidth //onClicked: SettingsModel.settingsButtonClicked("call") } TabButton { enabled: SettingsModel.showNetworkSettings || SettingsModel.developerSettingsEnabled iconName: 'settings_network' text: qsTr('networkTab') width: implicitWidth //onClicked: SettingsModel.settingsButtonClicked("network") } TabButton { iconName: 'settings_advanced' text: qsTr('uiTab') width: implicitWidth //onClicked: SettingsModel.settingsButtonClicked("ui") } TabButton { iconName: 'settings_advanced' text: qsTr('uiAdvanced') width: implicitWidth //onClicked: SettingsModel.settingsButtonClicked("advanced") } } Rectangle { Layout.fillWidth: true Layout.preferredHeight: TabButtonStyle.text.height color: TabButtonStyle.backgroundColor.normal MouseArea { anchors.fill: parent onClicked: konami.forceActiveFocus() cursorShape: Qt.ArrowCursor Konami { id: konami onTriggered: SettingsModel.developerSettingsEnabled = true } } } } // ------------------------------------------------------------------------- // Content. // ------------------------------------------------------------------------- StackLayout { Layout.fillHeight: true Layout.fillWidth: true currentIndex: tabBar.currentIndex SettingsSipAccounts {} SettingsAudio {} SettingsVideo {} SettingsCallsChat {} SettingsNetwork {} SettingsUi {} SettingsAdvanced {} } // ------------------------------------------------------------------------- // Buttons. // ------------------------------------------------------------------------- TextButtonB { Layout.alignment: Qt.AlignRight Layout.topMargin: SettingsWindowStyle.validButton.topMargin Layout.bottomMargin: SettingsWindowStyle.validButton.bottomMargin Layout.rightMargin: SettingsWindowStyle.validButton.rightMargin text: qsTr('validButton') onClicked: window.close() } } } linphone-desktop-4.2.5/linphone-app/ui/views/App/Styles/000077500000000000000000000000001376717241300231675ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/ui/views/App/Styles/Calls/000077500000000000000000000000001376717241300242255ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/ui/views/App/Styles/Calls/CallStyle.qml000066400000000000000000000044561376717241300266450ustar00rootroot00000000000000pragma Singleton import QtQml 2.2 import Colors 1.0 import Units 1.0 // ============================================================================= QtObject { property color backgroundColor: Colors.f property QtObject actionArea: QtObject { property int height: 100 property int iconSize: 40 property int leftButtonsGroupMargin: 50 property int lowWidth: 650 property int rightButtonsGroupMargin: 50 property QtObject userVideo: QtObject { property int height: 200 property int width: 130 } property QtObject vu: QtObject { property int spacing: 5 } property QtObject callError: QtObject { property color color: Colors.i property int pointSize: Units.dp * 12 } } property QtObject container: QtObject { property int margins: 15 property QtObject avatar: QtObject { property color backgroundColor: Colors.n property int maxSize: 300 } property QtObject pause: QtObject { property color color: Colors.g90 property QtObject text: QtObject { property color color: Colors.q property int pointSizeFactor: 10 } } } property QtObject header: QtObject { property int buttonIconSize: 40 property int iconSize: 16 property int leftMargin: 20 property int rightMargin: 20 property int spacing: 10 property int topMargin: 26 property QtObject busyIndicator: QtObject { property color color: Colors.g property int height: 30 property int width: 30 } property QtObject contactDescription: QtObject { property int height: 50 property int width: 150 } property QtObject elapsedTime: QtObject { property color color: Colors.j property int pointSize: Units.dp * 10 property QtObject fullscreen: QtObject { property int pointSize: Units.dp * 12 } } property QtObject stats: QtObject { property int relativeY: 90 } } property QtObject zrtpArea: QtObject { property int height: 50 property QtObject buttons: QtObject { property int spacing: 10 } property QtObject text: QtObject { property color colorA: Colors.j property color colorB: Colors.i property int pointSize: Units.dp * 10 property int wordsSpacing: 5 } } } linphone-desktop-4.2.5/linphone-app/ui/views/App/Styles/Calls/CallsWindowStyle.qml000066400000000000000000000014111376717241300302040ustar00rootroot00000000000000pragma Singleton import QtQml 2.2 import Colors 1.0 // ============================================================================= QtObject { property int minimumHeight: 480 property int minimumWidth: 960 property QtObject call: QtObject { property int minimumWidth: 395 } property QtObject callsList: QtObject { property color color: Colors.q property int defaultWidth: 250 property int maximumWidth: 250 property int minimumWidth: 110 property QtObject header: QtObject { property color color1: Colors.q property color color2: Colors.f property int height: 60 property int iconSize: 40 property int leftMargin: 10 } } property QtObject chat: QtObject { property int minimumWidth: 300 } } linphone-desktop-4.2.5/linphone-app/ui/views/App/Styles/Calls/ConferenceStyle.qml000066400000000000000000000012121376717241300300240ustar00rootroot00000000000000pragma Singleton import QtQml 2.2 import Colors 1.0 import Units 1.0 // ============================================================================= QtObject { property QtObject description: QtObject { property color color: Colors.j property int pointSize: Units.dp * 12 property int height: 60 property int width: 150 } property QtObject grid: QtObject { property int spacing: 5 property QtObject cell: QtObject { property int height: 145 property int spacing: 5 property int width: 154 property QtObject contactDescription: QtObject { property int height: 35 } } } } linphone-desktop-4.2.5/linphone-app/ui/views/App/Styles/Calls/Dialogs/000077500000000000000000000000001376717241300256075ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/ui/views/App/Styles/Calls/Dialogs/CallSipAddressStyle.qml000066400000000000000000000003221376717241300321750ustar00rootroot00000000000000pragma Singleton import QtQml 2.2 // ============================================================================= QtObject { property int height: 420 property int spacing: 10 property int width: 450 } linphone-desktop-4.2.5/linphone-app/ui/views/App/Styles/Calls/Dialogs/CallTransferStyle.qml000066400000000000000000000003221376717241300317200ustar00rootroot00000000000000pragma Singleton import QtQml 2.2 // ============================================================================= QtObject { property int height: 420 property int spacing: 10 property int width: 450 } linphone-desktop-4.2.5/linphone-app/ui/views/App/Styles/Calls/Dialogs/ConferenceManagerStyle.qml000066400000000000000000000010001376717241300326740ustar00rootroot00000000000000pragma Singleton import QtQml 2.2 import Colors 1.0 // ============================================================================= QtObject { property int height: 420 property int width: 740 property QtObject columns: QtObject { property QtObject selector: QtObject { property int spacing: 10 } property QtObject separator: QtObject { property color color: Colors.c property int leftMargin: 25 property int rightMargin: 25 property int width: 1 } } } linphone-desktop-4.2.5/linphone-app/ui/views/App/Styles/Calls/Dialogs/MultimediaParametersStyle.qml000066400000000000000000000006151376717241300334630ustar00rootroot00000000000000pragma Singleton import QtQml 2.2 // ============================================================================= QtObject { property int height: 312 property int width: 450 property QtObject column: QtObject { property int spacing: 24 property QtObject entry: QtObject { property int iconSize: 24 property int spacing: 10 property int spacing2: 5 } } } linphone-desktop-4.2.5/linphone-app/ui/views/App/Styles/Main/000077500000000000000000000000001376717241300240535ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/ui/views/App/Styles/Main/Assistant/000077500000000000000000000000001376717241300260245ustar00rootroot00000000000000ActivateAppSipAccountWithEmailStyle.qml000066400000000000000000000005031376717241300354750ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/ui/views/App/Styles/Main/Assistantpragma Singleton import QtQml 2.2 import Colors 1.0 import Units 1.0 // ============================================================================= QtObject { property int spacing: 20 property QtObject activationSteps: QtObject { property color color: Colors.g property int pointSize: Units.dp * 10 } } ActivateAppSipAccountWithPhoneNumberStyle.qml000066400000000000000000000005031376717241300366700ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/ui/views/App/Styles/Main/Assistantpragma Singleton import QtQml 2.2 import Colors 1.0 import Units 1.0 // ============================================================================= QtObject { property int spacing: 20 property QtObject activationSteps: QtObject { property color color: Colors.g property int pointSize: Units.dp * 10 } } AssistantAbstractViewStyle.qml000066400000000000000000000012421376717241300337700ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/ui/views/App/Styles/Main/Assistantpragma Singleton import QtQml 2.2 import Colors 1.0 import Units 1.0 // ============================================================================= QtObject { property QtObject buttons: QtObject { property int spacing: 10 } property QtObject content: QtObject { property int height: 375 property int width: 400 } property QtObject info: QtObject { property int spacing: 20 property QtObject description: QtObject { property color color: Colors.g property int pointSize: Units.dp * 11 } property QtObject title: QtObject { property color color: Colors.g property int pointSize: Units.dp * 11 } } } linphone-desktop-4.2.5/linphone-app/ui/views/App/Styles/Main/Assistant/AssistantHomeStyle.qml000066400000000000000000000013211376717241300323370ustar00rootroot00000000000000pragma Singleton import QtQml 2.2 import Colors 1.0 import Units 1.0 // ============================================================================= QtObject { property QtObject info: QtObject { property int height: 245 property int iconSize: 150 property QtObject description: QtObject { property color color: Colors.g property int pointSize: Units.dp * 10 property int height: 40 } property QtObject title: QtObject { property color color: Colors.g property int pointSize: Units.dp * 11 property int height: 40 } } property QtObject buttons: QtObject { property int height: 90 property int maxWidth: 690 property int spacing: 5 } } linphone-desktop-4.2.5/linphone-app/ui/views/App/Styles/Main/Assistant/CreateAppSipAccountStyle.qml000066400000000000000000000004671376717241300334240ustar00rootroot00000000000000pragma Singleton import QtQml 2.2 // ============================================================================= QtObject { property QtObject buttons: QtObject { property int spacing: 10 property QtObject button: QtObject { property int height: 40 property int width: 258 } } } linphone-desktop-4.2.5/linphone-app/ui/views/App/Styles/Main/Assistant/UseAppSipAccountStyle.qml000066400000000000000000000003131376717241300327430ustar00rootroot00000000000000pragma Singleton import QtQml 2.2 // ============================================================================= QtObject { property QtObject checkBox: QtObject { property int width: 300 } } linphone-desktop-4.2.5/linphone-app/ui/views/App/Styles/Main/AssistantStyle.qml000066400000000000000000000006031376717241300275570ustar00rootroot00000000000000pragma Singleton import QtQml 2.2 import Colors 1.0 // ============================================================================= QtObject { property color color: Colors.k property int bottomMargin: 35 property int leftMargin: 90 property int rightMargin: 90 property int topMargin: 50 property QtObject stackAnimation: QtObject { property int duration: 400 } } linphone-desktop-4.2.5/linphone-app/ui/views/App/Styles/Main/ContactEditStyle.qml000066400000000000000000000026441376717241300300160ustar00rootroot00000000000000pragma Singleton import QtQml 2.2 import Colors 1.0 import Units 1.0 // ============================================================================= QtObject { property QtObject buttons: QtObject { property int spacing: 20 property int topMargin: 20 } property QtObject bar: QtObject { property color color: Colors.e property int avatarSize: 60 property int height: 80 property int leftMargin: 40 property int rightMargin: 30 property int spacing: 20 property QtObject actions: QtObject { property int spacing: 40 property QtObject del: QtObject { property int iconSize: 22 } property QtObject edit: QtObject { property int iconSize: 22 } property QtObject history: QtObject { property int iconSize: 40 } } property QtObject buttons: QtObject { property int size: 40 property int spacing: 20 } property QtObject username: QtObject { property color color: Colors.j property int pointSize: Units.dp * 13 } } property QtObject content: QtObject { property color color: Colors.k } property QtObject values: QtObject { property int bottomMargin: 20 property int leftMargin: 40 property int rightMargin: 20 property int topMargin: 20 property QtObject separator: QtObject { property color color: Colors.f property int height: 1 } } } linphone-desktop-4.2.5/linphone-app/ui/views/App/Styles/Main/ContactsStyle.qml000066400000000000000000000025531376717241300273720ustar00rootroot00000000000000pragma Singleton import QtQml 2.2 import Colors 1.0 import Units 1.0 // ============================================================================= QtObject { property color backgroundColor: Colors.k property int spacing: 20 property QtObject bar: QtObject { property color backgroundColor: Colors.e property int height: 60 property int leftMargin: 18 property int rightMargin: 18 } property QtObject contact: QtObject { property int actionButtonsSize: 36 property int avatarSize: 30 property int deleteButtonSize: 22 property int height: 50 property int leftMargin: 40 property int presenceLevelSize: 12 property int rightMargin: 25 property int spacing: 15 property QtObject backgroundColor: QtObject { property color normal: Colors.k property color hovered: Colors.g10 } property QtObject border: QtObject { property color color: Colors.f property int width: 1 } property QtObject indicator: QtObject { property color color: Colors.i property int width: 5 } property QtObject presence: QtObject { property int pointSize: Units.dp * 10 property color color: Colors.n } property QtObject username: QtObject { property color color: Colors.j property int pointSize: Units.dp * 10 property int width: 220 } } } linphone-desktop-4.2.5/linphone-app/ui/views/App/Styles/Main/ConversationStyle.qml000066400000000000000000000022161376717241300302620ustar00rootroot00000000000000pragma Singleton import QtQml 2.2 import Colors 1.0 // ============================================================================= QtObject { property QtObject bar: QtObject { property color backgroundColor: Colors.e property int avatarSize: 60 property int height: 80 property int leftMargin: 40 property int rightMargin: 30 property int spacing: 20 property QtObject actions: QtObject { property int spacing: 40 property QtObject call: QtObject { property int iconSize: 40 } property QtObject del: QtObject { property int iconSize: 22 } property QtObject edit: QtObject { property int iconSize: 22 } } property QtObject description: QtObject { property color sipAddressColor: Colors.g property color usernameColor: Colors.j } } property QtObject filters: QtObject { property color backgroundColor: Colors.q property int height: 51 property int leftMargin: 40 property QtObject border: QtObject { property color color: Colors.g10 property int bottomWidth: 1 property int topWidth: 0 } } } linphone-desktop-4.2.5/linphone-app/ui/views/App/Styles/Main/Dialogs/000077500000000000000000000000001376717241300254355ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/ui/views/App/Styles/Main/Dialogs/AboutStyle.qml000066400000000000000000000017001376717241300302410ustar00rootroot00000000000000pragma Singleton import QtQml 2.2 import Colors 1.0 import Units 1.0 // ============================================================================= QtObject { property int height: 225 property int spacing: 20 property int width: 400 property QtObject copyrightBlock: QtObject { property int spacing: 10 property QtObject license: QtObject { property color color: Colors.d property int pointSize: Units.dp * 10 } property QtObject url: QtObject { property color color: Colors.i property int pointSize: Units.dp * 10 } } property QtObject versionsBlock: QtObject { property int iconSize: 48 property int spacing: 10 property QtObject appVersion: QtObject { property color color: Colors.d property int pointSize: Units.dp * 10 } property QtObject coreVersion: QtObject { property color color: Colors.d property int pointSize: Units.dp * 10 } } } linphone-desktop-4.2.5/linphone-app/ui/views/App/Styles/Main/Dialogs/AuthenticationRequestStyle.qml000066400000000000000000000002671376717241300335260ustar00rootroot00000000000000pragma Singleton import QtQml 2.2 // ============================================================================= QtObject { property int height: 416 property int width: 450 } linphone-desktop-4.2.5/linphone-app/ui/views/App/Styles/Main/Dialogs/ManageAccountsStyle.qml000066400000000000000000000004631376717241300320640ustar00rootroot00000000000000pragma Singleton import QtQml 2.2 // ============================================================================= QtObject { property int height: 353 property int heightWithoutPresence: 284 property int width: 450 property QtObject accountSelector: QtObject { property int height: 176 } } linphone-desktop-4.2.5/linphone-app/ui/views/App/Styles/Main/HistoryViewStyle.qml000066400000000000000000000022161376717241300301040ustar00rootroot00000000000000pragma Singleton import QtQml 2.2 import Colors 1.0 // ============================================================================= QtObject { property QtObject bar: QtObject { property color backgroundColor: Colors.e property int avatarSize: 60 property int height: 80 property int leftMargin: 40 property int rightMargin: 30 property int spacing: 20 property QtObject actions: QtObject { property int spacing: 40 property QtObject call: QtObject { property int iconSize: 40 } property QtObject del: QtObject { property int iconSize: 22 } property QtObject edit: QtObject { property int iconSize: 22 } } property QtObject description: QtObject { property color sipAddressColor: Colors.g property color usernameColor: Colors.j } } property QtObject filters: QtObject { property color backgroundColor: Colors.q property int height: 51 property int leftMargin: 40 property QtObject border: QtObject { property color color: Colors.g10 property int bottomWidth: 1 property int topWidth: 0 } } } linphone-desktop-4.2.5/linphone-app/ui/views/App/Styles/Main/HomeStyle.qml000066400000000000000000000003211376717241300264730ustar00rootroot00000000000000pragma Singleton import QtQml 2.2 import Colors 1.0 // ============================================================================= QtObject { property color color: Colors.k property int spacing: 20 } linphone-desktop-4.2.5/linphone-app/ui/views/App/Styles/Main/InviteFriendsStyle.qml000066400000000000000000000006061376717241300303620ustar00rootroot00000000000000pragma Singleton import QtQml 2.2 import Colors 1.0 // ============================================================================= QtObject { property color color: Colors.k property int width: 400 property QtObject message: QtObject { property int height: 140 } property QtObject buttons: QtObject { property int bottomMargin: 35 property int spacing: 10 } } linphone-desktop-4.2.5/linphone-app/ui/views/App/Styles/Main/MainWindowStyle.qml000066400000000000000000000021111376717241300276560ustar00rootroot00000000000000pragma Singleton import QtQuick 2.7 import Colors 1.0 import Units 1.0 // ============================================================================= QtObject { property int menuBurgerSize: 16 property int newConferenceSize: 40 property int minimumHeight: 610 property int minimumWidth: 950 property int width: 950 property QtObject accountStatus: QtObject { property int width: 200 } property QtObject autoAnswerStatus: QtObject { property int iconSize: 16 property int width: 28 property QtObject text: QtObject { property int pointSize: Units.dp * 8 property color color: Colors.i } } property QtObject menu: QtObject { property int height: 50 property int width: 250 } property QtObject searchBox: QtObject { property int maxHeight: 300 // See Hick's law for good choice. } property QtObject toolBar: QtObject { property int height: 70 property int leftMargin: 20 property int rightMargin: 20 property int spacing: 20 property var background: Rectangle { color: Colors.f } } } linphone-desktop-4.2.5/linphone-app/ui/views/App/Styles/Settings/000077500000000000000000000000001376717241300247675ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/ui/views/App/Styles/Settings/Dialogs/000077500000000000000000000000001376717241300263515ustar00rootroot00000000000000SettingsSipAccountsEditStyle.qml000066400000000000000000000002671376717241300346150ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/ui/views/App/Styles/Settings/Dialogspragma Singleton import QtQml 2.2 // ============================================================================= QtObject { property int height: 550 property int width: 934 } SettingsVideoPreviewStyle.qml000066400000000000000000000002671376717241300341640ustar00rootroot00000000000000linphone-desktop-4.2.5/linphone-app/ui/views/App/Styles/Settings/Dialogspragma Singleton import QtQml 2.2 // ============================================================================= QtObject { property int height: 480 property int width: 640 } linphone-desktop-4.2.5/linphone-app/ui/views/App/Styles/Settings/SettingsAdvancedStyle.qml000066400000000000000000000003131376717241300317460ustar00rootroot00000000000000pragma Singleton import QtQml 2.2 // ============================================================================= QtObject { property QtObject buttons: QtObject { property int spacing: 10 } } linphone-desktop-4.2.5/linphone-app/ui/views/App/Styles/Settings/SettingsAudioStyle.qml000066400000000000000000000004421376717241300313050ustar00rootroot00000000000000pragma Singleton import QtQml 2.2 // ============================================================================= QtObject { property QtObject ringPlayer: QtObject { property int leftMargin: 10 } property QtObject warningMessage: QtObject { property int iconSize: 20 } } linphone-desktop-4.2.5/linphone-app/ui/views/App/Styles/Settings/SettingsWindowStyle.qml000066400000000000000000000013401376717241300315110ustar00rootroot00000000000000pragma Singleton import QtQml 2.2 import Colors 1.0 // ============================================================================= QtObject { property color color: Colors.k property int height: 640 property int width: 1024 property QtObject forms: QtObject { property int spacing: 10 } property QtObject validButton: QtObject { property int bottomMargin: 30 property int rightMargin: 30 property int topMargin: 30 } property QtObject sipAccounts: QtObject { property int buttonsSpacing: 8 property int iconSize: 22 property int legendLineWidth: 280 } property QtObject video: QtObject { property QtObject warningMessage: QtObject { property int iconSize: 20 } } } linphone-desktop-4.2.5/linphone-app/ui/views/App/Styles/qmldir000066400000000000000000000061561376717241300244120ustar00rootroot00000000000000# See: https://wiki.qt.io/Qml_Styling module App.Styles # Views styles ================================================================= # Calls Window ----------------------------------------------------------------- singleton CallStyle 1.0 Calls/CallStyle.qml singleton CallsWindowStyle 1.0 Calls/CallsWindowStyle.qml singleton ConferenceStyle 1.0 Calls/ConferenceStyle.qml singleton CallSipAddressStyle 1.0 Calls/Dialogs/CallSipAddressStyle.qml singleton CallTransferStyle 1.0 Calls/Dialogs/CallTransferStyle.qml singleton ConferenceManagerStyle 1.0 Calls/Dialogs/ConferenceManagerStyle.qml singleton MultimediaParametersStyle 1.0 Calls/Dialogs/MultimediaParametersStyle.qml # Main Window ------------------------------------------------------------------ singleton ActivateAppSipAccountWithEmailStyle 1.0 Main/Assistant/ActivateAppSipAccountWithEmailStyle.qml singleton ActivateAppSipAccountWithPhoneNumberStyle 1.0 Main/Assistant/ActivateAppSipAccountWithPhoneNumberStyle.qml singleton AssistantAbstractViewStyle 1.0 Main/Assistant/AssistantAbstractViewStyle.qml singleton AssistantHomeStyle 1.0 Main/Assistant/AssistantHomeStyle.qml singleton CreateAppSipAccountStyle 1.0 Main/Assistant/CreateAppSipAccountStyle.qml singleton UseAppSipAccountStyle 1.0 Main/Assistant/UseAppSipAccountStyle.qml singleton AssistantStyle 1.0 Main/AssistantStyle.qml singleton ContactEditStyle 1.0 Main/ContactEditStyle.qml singleton ContactsStyle 1.0 Main/ContactsStyle.qml singleton ConversationStyle 1.0 Main/ConversationStyle.qml singleton HomeStyle 1.0 Main/HomeStyle.qml singleton HistoryViewStyle 1.0 Main/HistoryViewStyle.qml singleton InviteFriendsStyle 1.0 Main/InviteFriendsStyle.qml singleton MainWindowStyle 1.0 Main/MainWindowStyle.qml singleton AboutStyle 1.0 Main/Dialogs/AboutStyle.qml singleton AuthenticationRequestStyle 1.0 Main/Dialogs/AuthenticationRequestStyle.qml singleton ManageAccountsStyle 1.0 Main/Dialogs/ManageAccountsStyle.qml # Settings Window -------------------------------------------------------------- singleton SettingsAdvancedStyle 1.0 Settings/SettingsAdvancedStyle.qml singleton SettingsAudioStyle 1.0 Settings/SettingsAudioStyle.qml singleton SettingsWindowStyle 1.0 Settings/SettingsWindowStyle.qml singleton SettingsSipAccountsEditStyle 1.0 Settings/Dialogs/SettingsSipAccountsEditStyle.qml singleton SettingsVideoPreviewStyle 1.0 Settings/Dialogs/SettingsVideoPreviewStyle.qml linphone-desktop-4.2.5/linphone-sdk/000077500000000000000000000000001376717241300174135ustar00rootroot00000000000000linphone-desktop-4.2.5/readme_screen.png000066400000000000000000003220421376717241300203250ustar00rootroot00000000000000PNG  IHDRD^sBIT|d IDATxwxStz/-۲d0ŦdndSvL&B!Bo+cp.]ƍ?%B!B Hmm-v159tpzHpj6l0%B!B ġCu}b&۷osvلB!ₑH$4 x%]7Kw s* ?3B!B,q.ƻ(,_/|`ܹb[uh=7tXB!BwD"1Ex@HN2ܺ ݱlg9B!J 4^/zB!B[H A}#Q 씈W!B`Yͮk@Jha4歅c/amiB!B[$@3 !##`08}Sqj(*oT 1j`wB!B m[3NJ}}='//Lm{uܵ^;=nn\_Eߣqϴ/L!8:Z>y衯ZB!L̖$jkkȑv(SO=@n*<'=[֌raٲelܸ˗_<⮝ˑ#G;IJ,zzz;.knKg VLwiZ!+x32.iB1nV^Ê+xgGvO4"<B2M˚Um9r;HΓO>A"a{6:# m۞PYYIyy9y<u]dddEeʖO;Swi a3'G07TmOnghOO8X"^!Sq?#4M#28N~`| 㜙<Bqf:upÇ뮻G]<ρѵegpWzM} _Ķi]0OII ?Ї$''{EQHII'x|> L~TJ$P*V7m§?!^!S1{]]=^{-w}7@ 6F[[| Ȇ Z !xgj?BNNƮp㏓~<--msUW۷i+#f n+ܹsys= @WW?sJKKHQ* c_ch"7Kαv xJׁ'iΉ瑗%/ykk=> PSS=K/ΝF[p!uuu<7xx챟24h$ݽ;k_:7p,Y~TWW9^xyկ:$}}}A=K^򒗼·if/˲b455c2ر&q۶׹x-.dt^hUUt]GUUg-}mTwfUsa nEo<E]]x |_?)?я(**+Wd]'MO?P@ !,§?&Ñ#z3N?zZ*>)/_INN<أ̝;pv+Wm)>nϕ^W~:ux wFo;4Wk ^{xܝj Ӿ`!>q~SŢbQRR҈ŢÃx>ݻ+￟KiPUut!>ׇ(ضM4!i)z}6Rn,/_>yu' ^h!'~.Ė-[N/?yNpjVZ޽{).CFucg/^yML1Y;Oqño [JSav?+^l _YSƒ,ʌJiq| *JQ0}F'Je˯Fm;}qO0e$ko+o!.hlf(B!x #{{{xiF;fxJK+4IKKb!],--mL |.pVP~"-ӛ>9hj|а7(c݆lK;>@kKq@srI1C6HΧ(ǔ!k~8s4]ex[vR>o̓#'A{ M1, C}ČdsFv|)hoy@#뉢S1z>+JOODff`'z38w:tX%ݘB1=@0B]xw6GNϲ8w>T?=[ |귾IEcצm/ӵFY\z=]~6lⱗ"6"eSTKO{}>իԍ\_/I ##$~-B!9;" ۧ'fꬶ/=t.dT1KSKplx$b4-CtDa c9t<U =ƁV]0w\uU?|3 ۸1O^?^~qkx1z߳J4U?kuo v sbiUB!b_ E+ey0 w`^zeVNucEl@1{5~ O>;8Lڤi+Chp4j$@ dQ9TLdy;FwG?'??u4~ w b4()>?N\hm0tpbL̯(`W!Bsap]ibH+t}؜rCNjU [v,Zk\榩8;O6QYq7]<~~M#ҋjA`F- dtB:i&}q{(7v=JdƶtMadr`W^^BҐ4{/g B!BK`ɩŠ{۝fu?/ ~UwߛnLx!6xdǙkpD p 9Q>bmG9:Ar2}xyx;K`-w,p1d@B!ABXalV/Ыne-qaMCB'j;W (]}ut9DbqشO &kgΠzw>@S)f>SB:r`!0c1b(]}7imnh$z麲/fѽ.V-8%OK/opGܶ42 ?Jn2Y:;zygXJK%\Uŗ/'|Hf'Mв;}l4tmQ˷RV/~C:ϧFe ȟ{#B!Ĺ8ʹnYh.Ș|“7nl< Ka+[imO6|x}}*RK%~KZzJjS俅c(]VzIQ5UQTGF\245w nᇯ4VFk>p_7)SQաmş[ГXSX([өhuE'o~-47@HPԕ7#^"|pjfזDO2neC^[~u{wQ(%> QUEB!kii v~?x<"$ >a$''"ĝ߁mn8UWBwӉvK܀wm# wLC_ΰ9tN}XQʃ>|  ؘ,:>XC儩ql kxܪh6Y9QBOR>m82OՆώBt/$/I3Z@h8L}xdNJ3'&mH8L\L9(Z _zeg?H:`B'eG;:$?1ٖ8vVFEEv,tİ54R81Esj9kx%ޙL:o)X~Êu H=Fرu)d! RUU@vv6C 4.4%zY|9:?;v 77`Η'ߡ>'`'_x)|i6耢27,`Kxh៶~}ʖަްw`oٟY`URPKT- E[Y[iK$0=i9t)cLL4TSPn՝SLjɜ |d$TM;3Dh9^@Ї2V)X]sw:}0<|DZlZ­u(<œQ߈]ܷ|:it Y3K#^̞DX/nvw?!0 R*++b]YIƽ}>f@bv?-Un^b {x;n3J9b$Y|}uvj6)DP.#xZhQZ$α:r`'Wv"AQuQ 86* eb*1b8? CqI$,tt!ma&l}±M"Q 6ub2'ho kc 2ܳek4-pgo'J.ض=&)n}H+pgWTu6\a}흄R)XɃ5&a&p;EϐcnLkAE&aZ?Hu, kz{q½'ym 3aƘtv>-,ipНq8--`w<6wbSc%}w.OyA4\s7bv(_K{މvPְ6b5w޸XXj*%eMְVCq =$sX` tE+w{m+r~$05Trh; <zU<%-Cv=oV[$s=cdp2 Vt`V(AJ+Ph6`XZe `s;: 8 )%Hki0ӷתt,{^XG-{A_˗hWO onNIaEȋaߡf ca,(_Na@:}7c'Qcbw:ԅ.k߰ʆ> VEO&m­m'l+@`j*J| ]%9fY4pWGKXE!J޽d5"rkCn *TU29Ar] IDATIϑJ*5e%`^oc96Lq JR5p´T+m+由OWNc8n67($]źdiB,m4FoI;/8T8u?Ⱦc{jp'J߁: ?p.Sʤvʧg;po1,iF_8ۥRP{7yO78ZЛK+21~GUC),JfL)qXK'FS/[NPSQn+0s˹$I3U|$P &Xr=+T]?@e}u2Pg\1 slnz[\5 v$k*jeS,`8|%G9P&szdzLJokA+Xmp]g#]̺\/ &yX`^+) Gϡty))^T'J]44(;F./_I*yh;vӓUE>NHT dcinT6uȑx嗖 bw!tk`:6{PBPٱ֢ #PG-`(NѰcL^K)q:PCyx?ŋXJfW olp`%vp, SM(00MH$r{sQ3Omt!w-6u>?7D`& >Ӷg`dzܳX" Bߔ$VT8}l{Zbݴx 1UINsRxp(p<bh=Iw"9En[2 IPP0RIQD&[ tBfE ' %JQQha(n| PPEK"5p1b laxJs2ݠO5GQuXbت?ɋ ($%(Ho`:ẘf2e%q0"$MܜX."||;{ߣ +n(I$ !:LR I(FRn1ڻt32/ӇN]L#Y"ajIZ31)~~9=u!,!%=(KIï$F"u?~LK9E] !$5՝Xl];;;ݥp14c7??}64Ox?a}碴'e;biL0v:WqSYBEBj_}Cu%ň15u'!sb8q5ЎXϤct1PQ&EkcC#*ԣuٷ:#E)ɘ)Cć˓Hm|cipbt5X &F`Mcba:H}6̠&fBSxQ0&bb TUEC(lH:@Z3yG1vˑ 9x|>3fBE<{RRR&<@rLNmа"q,& g@K"w~9%qz8PyﺕL<.:)_tg;5a:\V_2dp#;wtN;!8hƼy󨭭%q!^:DbAYAoZ K鯀!9]h0́t9q.BZ8Cb~Ї 79F[C-IDpvg-V'IҒ3IW9vcĘ٤:)8]h7rXQ1 oziv؀X/zFy$ņJר $mǺ9F@FF qvH,c9L[dB QXzH wrE31Gkȭswe;S/*`t5Qٌb]-tL:K!)=o8Q~mӽ^u8p{+3 ^[5&Hk4@vSr:S,2HLle}Dpl]ǝYFRPb{:CCn3vڡ߉us x&!y/%%Kb 躎eYԌ| ×_wgbx u×sJͅ/os&_׃?;pY6K- HpO5Sf<;.ښ~9x.Kr%fAAJzIڴZ#ü^>'~T[LJ{[f#sn.SY]IbdF  +r@ ͵(*8Fpn9kPXdwv6k(*wY,\V{ܨe.梲ZTzNֲ rrX,V6z\dÔOYG:ǵ$ZEaa{mgs jL~7@JX> okY] cuoA5,;i`8Vtۂ@22)hj6Z$WSTclT- &Yi=-:+Y]|  FyOɼVffy?ds:}^\=^o_OcGzZw3m!^I'͖xb͕^L =O4#7-!eidm%bϳq|hdmmmTTTLXǶH&{Iֿu̸n1~c{ 4l,GASw]WTuu_3V rl,A{9xIx Xt9|}=Nj5ղC.kZ) >v!g2K(fSZs 濜Nĉ{ǩXxX+rT4! i5~}ܗh̝k'E,fbk|Ɖ_j^4ѹe>/;v"FTx=cQ o◤/#NH,M2ix=c.#y ;\>>^9U~]E,nhCk6 Ԇ˩3/ [\8ҁ~z-8>|c#Kx|&4C1$ƬxLNouG[gj^$P4;[E3Ƽ=EEjbx}6MNdcI&\jx[)qd{{E &??yMX#N,I\Q ^MBA9 ]kL:V&=LR21BO&>'y)g*oIbcLUޅ ~ŋ02yͶᶯƽ0w;~(^ˡj4 lM3 MSv>=;vM̐g-nv2ZLTƴ ]m^Dj_5J&aU|}Cx|Ά;ndu2ĎґPT/~ӰE!j8 yW/ or 3oSl%+_P Ł%|/QD/^k5pmku5fvPTǛ˺k|=MYYOmc),x-/p}<7 jk۴#/%g[b+ͭȿ\Z`s|VTwCJN)\b{b>4@_VXJb>p:ڶq)s9K SiĠcck8E?e_ŷv?<=jn]AOgt%}eC7Wůh3ncY*YWr\ia󟷰DUlsWpQv'[~Him,qSYۭt0/i;n}VsȾлw/%HqylB!x[|>/bLCaZ VVvK5솣;ǧJ(p)k=]Ҩq7b#nqcrVG34[M`2qqin$tՍ|}(^zv /sh"?`JWzS4k,܀s<%lSlw٬CAU5,`+8vT"oBwwoW_cW{HQu 2o z}͋ouFzA!L]-w~"MMzv_2/;_~9WWl&^؟ˇV V^_](ǷsĻht}?6suI;AQTG,gg+Wƽ` ٤pgS=Զl 0iy~.o?%Ƒ# {,HV vu@Q45C_~y útP,J}'6zToJ%w߷L=Noue0@unЇރ/4.R/I[||f;[y2˛B!x"n p+{4^|}=g|A4Ro~3~lHW@:S $ЂŬYJ߱Vƍm1ŊP<,[;{7#\Ex>%D'NcЂ?"mή>bih]4vql 3L$H` ~#MWPT@jR0HeTE#t+mljQ sc((A,PZ9>qPȜ"N׻8?F]o t򐟟DOs;!71VVdTtU!ՇEKMm5eKM"Iw5CxKhܻ(%=?ōa\x(\x+ 3JQ'[ ?4@ʼ$k(h_>O)H5LĆH+5-*+ex_P* 1ǯVG5@fj_'CWH'/?@_K!Bq2ӿuܥ[Ĵ^#o w/ͯoH/]380ctCEN? 7iQ>EQ`AĄΘ k}U\!9 ǰQ"ALUkI}"C9~1zǢ5!F͘S.+I4:H+aca^3S 1RURXuxwŶU>k6^Eu1 OHZdR_w4V x5AB4j`O9e(CLyt?AOZm:IIc[MoG~5ƮLqF[!Bװкk3_Q ܥ\m`xTāv6Nd&sf9w&}gfw6kwvwv2$qH| ܇B}jUIH@B2_/^/Ut~W}t/QMf<;J|Kz8{J=䥩38uIKPImFƻؘ ?U ^ y=>OhMm~&HM#ΌMx /6IDp(C8)=U5sycY6Ԝ)ȄʳWRVF%Y4J\K+za/M}޺3^sqδE%?49t,5υB!_֧® (K)^<%la5Dl?;aFYSͿ~uliE<* rN[dO:X=Y %ƺr (<jbOϧ k0!Fap{^7v),iSIy2jwu!4Č+O3>o◠ś&QmL{xṓaM-,q~ jYmzvDS0-'l ;j6-Nc۶ ,f-)>>Oi шʼUwtn2=Mӄ1*qv lr|Bq(co `G_~]&躍u(NTBe2,޴w玣5Y"G{ jnz;4=9$`p2 (KIKMa !J^y:<ۡü+TVVv(B!h756Hv*t:`2Ro^B9|ӧNv(:}4o !B̢6w\r 4(Bu,̡h4UiSy≷+>᣽'1Mێ͢`bDz}t኏c΀HIb K")Ή6rg#Hg̬"ĜoHv>uczL !Q5tt{C!.NbTb\Yx8/@mC8c 1.,G,>.nJ;dwZ ä`/BS5*k?HUæ)cl`UnSq'Rx{NbpvLUMCU(taTEeSAa9dZO{nc9|0<B[L01x}*9q27ifYoVCa.TQ:R(XnY!Ox&'JhitWj % Y8UUh'FuĒRt0@Oo(ą ]MMHe :ǎbTXyf \ ~;aL={7o[2ۡ!Du՜!ٔ21]^]J_0/ey9X31뜯E,Ƣ]7RMxfgab;YYD:516NᲡ{ ״DNݡ. "rZFSmN\JV!9TEQKfV&Ό/s(FaҬ.> >/*Zb6$];D!怚V MѨJ.Vճ~e>YSܱL{z_U_Ov/>~f4H4iS|( =^X΢Y3*hK)0*V=!:Zë%1XXАNÁuӆ6]C*RaiDui~1d3+Ba>8VJQ~.+L4M\ř? W,^L_|h[x{Y|)ϜwJe٬V6VDi%Ȅ`(4*b!9=V30W0 s&a qM[\e!&1N2W|"?vCvCfǹW~?7ˢvc p4iڇwICCLxB( I]5LXrD51+}aiKǕFnztz鎨x(^j+j鰥SPG{3SZ$ȕNX22Hu]SwBu'恎j;tɛUo:^lOyƥPv79X (޾ I1CWT{nD KL5]z(f$RUDZJn֤7 sѵy;G;hIx0 {h6^BnUUPL4G9^ߐͰFu' Q-MѣdW.pC['yhcGrk<[+Yzt#yVF7K';Hp{g2w2 B^*+ڈf3> ߼>fQC2f&T:nj}}?Ȁ,Xվ} jyS5;Ήޙ7SP饻#Qn7ɠa\=O qިyNpAmڈB10*wq 2pF7`(̹cǿ0+1L7?8LMc qٶiFskX>V_[} ~7yq7$pn31[wGKZG&$줦f7y+7}?]d9PMU4w7]'%JJ +d1]5☾  uT7$K!e|=V\Φ %555tvv0s#uQ'w(B\fe;*9eqHe;LP S,rY=E8n.<3HM~qqGO}^:ZnHQ8JOsef\ 皣eX4]<3cP!nQu/+uB!BQ^UO4:z!O妠K}s۰TU4GQWQ?V UuDT6!ևf9=f$:U.*JMvp$B^V:7ޱ5$B)555twwOH+iw+H@Ȟ~kUypzJ3Zqe|:SE~‡\ :H^t3Z80NMMM'8Y=K\DgX}QPͯOwm%܍ܳc&^'ٟnrrS4CRI*`Ie֥3|RɈ-cC?z%${z]_}y}1Xw9nWgIvǧo-X1: ~14s kr>l4Hoo0.'.6URqghN71a=lzMqPH(4\1 ]E_06n!(\t =8 U碲tȏ8q`|W1C&N0RFuTUe.^@}s .AT²3^%G"ӊmm$w4\b&kͣn/^W=% PnhbqڭdKwߺYVjܔ¥+KqH!ΕWLSTB}FPSWs׊tʞBM,r:>z<)S9R,<ZŏMQ&Nl}\8F(k"+h˄'BV41ן9F(hv72fWq9N;nɉPSO@=t6l+ ͜ρgnhHsIgw/ic}RUԤx$zKs|`х`aVuMĸ]$KBlU7%wͨJ16N($bЛ(9pt@q ,.DOqroU!ĭ󸝨JR|fC&xx}}vb&ZY@e]㙬rq}[;PTLojNXH[W 8} ޜi{Mni!adL;pfw 7:RJu&ui{U!ĭn&B_oGHT'-%q믽HGn㞙q.۬ONgGݽ$`NfBl %{J+S&VliKG{:cIǭE8ym'_f%3Ro\Ϗ1:ascCWg,ӰZT'~z+'o^p0[;qFݶ;n~R.U:sa̦6>8ZCwuE!\Ԥi?>6NH5[wAZxs1KE˜jwak##L8!5֤UUABQP;3%9sBqs:?ލZ84>uIʹ>Mtv{)*XxͶfMxLzqPxݳ8{+@yUO=|cgBl }ʯq.4Pxݚ1+$B)d(I珟yg~g~\GqGOT\I r?W!NZLcc\m]faIozj߷ƾg| ߽N$NXDqc:FG>~Srөi`}R=1,ן'1n{D7 c}Z4ڴd hhiwwhLz?ubcOz'lpu+6պUN[,J+V !攔w`4gϙOQ1 ũ΀>.<*<6~z{.N ʟʹN]*.+<}ib30tKd9٩G I-͚zH'X0}\p E&ČNKsVޡ~'oN)FH4YձicM1kf͟X{䡻6M>p^}巈Dk]=)ºfq⿙ݩijxٵc'9m86c񍱌b?@r|vu !dvqw(_9 y7^UOFQ?™fGiNҹN aǪ8Y) /5 tSESMAmzr5#?A;ph`ʐ^p@bІ$&ӎUL` ac5F˦L"AӆiVa(z_Pp=iِ㢡 Ca҅ψGp_ kt,aӊDW/(?/ŇY;PN("pO[3 \1 ͌FQN'`bǗ?l:aQuBQՎ~=ܮ脂atר 8m5 }=(< BVk<6\јDPT09AfX}!&+Ɩvꛆ-3 ʹw {Te^)!6|:y;y jZ~qji-]Xyz⟙}1nqOX59ZZ9 E8z"k}3I+S{RDž懿X_|y )_/d{T4|Txcf>GW;("四}z(Pp6akj2mG^WgS<ӝ'+8Y.[|;DZ΃\𚨦5O?qcU-Wv;G+͒g%T4Fa yW^S*j"~&iĵŅUxM]eCɥ1E3W{8AQL<,R;8CS0x?ħ 6 S}M~~` ;PdIቕ1t\8GhXe]|^=^ϊ赇yu5c8O箰́_ʕxK1f=Tqo*^>>crx_[DliʼFm+;IP"\y%X}^=j!mv'gpK^h$6.ݑOD97y:Z큇x;_TB\(*hG5v?_77@v Q4t|仯}7lh<'h/RFNw&2Wcy. "WTg;I2^1d=k}G֎nVYi)Nx6}o Z^vHTۼӄlgD^|CccI!!.ۉŢꘘ饣K{W^:<I,a>xdž3^tW1$$$Mii$Ҹׁ揾W2*z(?'`w:p8شc%߿K'pl 0Aat`ZPp$$$L8LvDT`\ f⫮˧P+x<7HœGrn Rϻo$Xؖ3W^hn_Qvz%[3q=~uv/"y+_cImyꝜk4'2θB?{_v/m  ȩ-|[fR~Q)/H5jCYf HҢFqt⍖,-x}~.>#~.,lؐym,Up#m¶GvofK4Ey09pڐfF:ש(A+L寳cvz?x},4&6\h1~#_Ù|#˞M9s[ >gN[E+şpm>Ώ~~x$ ?zwro΢s{7wq q$Be^Wx&BCΣXI!1 IR9+7oc<_Ocv"(qs׺"Rx#׬{MF 2VR(/]^;PYG$%Gkg7. BBl qf'!6fԱ7*-9ǶnroIxsN)$ZR ?M+XbwᱻF4h#2w_O8~NrSpzl <40=%0 p~㳺=8.@*;IfW͏ -+z:7Vs7Mkp+#52pOhK%|c]1 `c>%.t DU_Dz%͎Z.tQ#8PXYûU}-fg5$h & 2KpuI+ >'phZ68X%$[Zh¥ҋ׽7a֧ĩKܙ2t0#즩DM!8Υ"-gs\I>X6cŦp} +qVNMlȍ#. g0 IK_Ja1+AyM (D\9Y@l),9CWo@Qpd.嶴+٘s=UmD( Bd )ڼ{8X!i}Ҋn6'Y1Q_IVTM.1MYpG26DBki7w^$}z*e II9o#-02l(=S#T gUb(Xϼ'lqجestoy9f(\4uTe\ 7+KiaW.Qf/'^Cxbqb5BA~/>KNcͼ?[}>xr Gϫv'@ !-QŅgHvTE~BӍG  N`Tq?\,./Ճ~XL%x?'֩?<֍ 8m[|Nb]#~ ޠm Z OxGոLجh躂wq^Xi!N£ɾ|Gأ&Qv&ҍZr\jq4 D_ g! vWԊ'J"wqĸ0h_H!Ph|At#q2pCҨ] *Ɲ@tă$=' Y]DqՂx:}>ot;~Q!!ey9\'{\X7!8)'8 Ӥ6+]86t NM;6M!~qUܹيCqh.7N o3ǫۙ+ՁS hFBFoQ!FeT֭S4}֯2nMc4 G&Ԋ;+3͕)xū<\( ūg|k#~[bnpd5`+& 8Abn& Jycy"`Ib㧛`{(;[suKj>^^-#uc SV3Yɩ:|ǔV3=aEz8y0\>VJ]l.Rh6;NELs%ڢ`bK i:u>0|#ͱ,]?&i''? DKlIDiɼur 8dz-Ŭ,z' c- ]}銝a\W@Uy.|ӽ,r* AIMaLLuVY4~«%Č/+n"g}xB0wOtu-/l|_c>P,h%|Iur*̂ڌݜG`70W:6։[v7dXԁKgE$;(Rr4gcSApsMO+?ᯂ&ѰB<D к42og4ЕXV0r޻WwuŪb q+x|'TbVI]|M,蘞<2|mΥ@dۮsAV.ɥ룺֛:-% nX)&O|?YG1Ӿߚ&<_g]Ɨk֮zh_ DD18!%X-ٻ8[U929k4FFalKz+K~J>>gr,[hrR8 `Dй  }Ιsƭ[ư>b%{Ȧ*!1eMpV'r_y*Pcn_`cd)!qEѴQkʾERפ,_}o=u!|N!K2͓LNLt_{b]['vH I7ӣd0eUeh{4~Duye8 C+rѯ~6`rXnpmڤ YRy|x&3\ !`Ҥ $2:eɧ3dw,Zt#99|!ĊfZZwU]ܱqŁç,]ŭX/ !V]wq~应M9yZ8^Htq)^N&fvmo3rCp MRtc@i ewg D 8(??эUy;T:@pRQ+\|\CW:эi0\W]BY>fLMiW TnyLdD}> n՗t7]2.rޣסЍ&++hz癎 ״/YkC\W ]R uuT6ýhU<^l[s/t-IJ1t;p,tq+7oo]Ӑ ]gDnŭM^!Ċvstww/w(R teSmOM9.dK]7J*֫h͟GV\t]~n 2!Z*,fPJ˯l)uk:TS104M*]٩D! 3 ^qw[Mٽ_:~憪7_fVY+WY7/_4psihʡ>2wLm*%;*ĉ?AEThgؿ*c| Ᏺ'-`^~+b;-F`sQ^>g14K dy M0u&vT[I]U9wp|;ys CgK*667P5*^=ׁidΖu(SŌ$BxGr2;[7l9$&w-HĹGM_w: /ӏqynth!/,Eo&rX@Ie5Wsb}$R#XSIb_Pe -9s_]#S5$Bp^Ku?jzQjdw‰?J<~σu IDATR(6u޺kHert0<"˓J{۴beAj⫴kzܓ;8+ }UH+%b1|A,G]p؁M?Zv%B~/;nʵbַwl_PXUG\{)ۂǰB!J# ▲fwsw-w( F8!B1$B[Nm]-|;yӛ߄a,ʌyc>B! [OӼLaηwbYr'Xby{ǟX}z}v+՘E4Bw.n`B!q˖F#aolZ!. 6#cVo>8^8nd=nt(fF V !B,eIxáw؊Rhs:M&( XhYvl幃GHf֬YCkk++qUM/;]ص   unPQB!kݒ'ضݽl;?`|a64ZxE*ڽ]wqarWOJr˴ ؼe3;;J/:&Zݐ: X'5QYfԚFb B!j޺*tSg/88p#ek_P;JhWWNttt0:zcUhjjbæ lܸ nAE _?.m=4DqP<*~3)B!c(죶uk,J+xH$ttt 8C!r\׋祢r*++h4z3)\6M=4N#P0w< F 4+B!b1,yzKv,rBܨh4J4etwZ{潋t!B1WKvi!tc -|6C2\>!?^Vl&XAkw0Bԫȍ0Z:yCT HR؅ȥ36 !B!,y ;:ki#T_3~b}ab\"N HgF1xn\.'x\/ $GHOJ))rw:)2/FxЋ){&#[C !B!n-Rp4"p%6斵>wt:#ݫ[|bUE(hB!B<$᭫dǖ hJSq^hGS;lr"t5-S(5k⧔ǹ\j4'&p#+u7´ Bpc>xA-țj3%ebT\ !B!nVĢl܊R ?uB8 "OB;J)on"] mR5ni(5dݥls)ϩ$)M8Ø>LJGwr{[(YJ=CgsL۸~$UpP(r&v!hCy$F6h(4pY?9')F*^hy2\UlJS(Ꮕi$Ʋ-]. ;Ox,[@!OQhH]RKJr B!ĢI$Y3kpö 멭ZȄs$VY`R(̌˙Mvt!+L$ql|4 K&I{"4\p<JH;,颏ύVcF[DW p,yfx* A.h,B!KiQP0pb gt8ϨRhB9dvJm-&/Y)pڌ+0CkI 3ӿ03 e&O3S$&ʧH883-+'{uAJW}vf>!B!X5u\ 3_O{Q8ql#,ٴZ\cc]gHvwqpwB!B`ZhM 4ioqB!B!ĸEMҔGʸs,fd4X*E:%Β,Ӳhkx=p0H,>^9>2 !B!-j{6֮<!S-΁CG9sIϛWϜٗ^a{U7o>ghhQLs'^(( d2@X,F4~äe߅Q^/h =B2Ix+R:xCdd*s/fhxŖu#dhhd2.t:M.#SYY9^˲$cY"EykrR(,wHB!-K^!ĊԁC;iNH&vUÜfd1aYNJk8C]]&%7B!OP!Ċ<¡cVݽmTx\ne BT !VW/yu9ǹnŭ($'I)Pum;$B,&Ix+ʉ3;9{y.u\M6T\^q$B!n$B%^o?B0Q[Y>_6bv|^ !7@^!Ċ22z#YKmuFފ͟D)u;Vnj׹'{v}7~jc˲n}BfʶDoڻyB#עU&^Ïҋ|7c M;~8=ry3r*Bn bK9Ai=5VgLWFi+)on&0FxHj#n t/* fƖFn]Jp8ɘbkVXCp${/>l^ESuTE.KU-u]mtM~ Wpk؅ Է&_EU:Pz:&v.f︿m}upSyc'^Pha$g8]$Nbej }rK!M^!mv;S'8x$Vs:rt\|l:ˌXh a$+=S0C$TZVSaX##Q槎Z;.µ46 8C2V6S_5s fCj]GCE'F$FGI\Dm[LOV5[D'Xp9 '`0u=SBt+ |g=KyVok1([nlŝ52Ad(Q dVs9ߟS MDntx9F(#у1fiKMrtt:M耓cvEhݰJ'Ov@T4@ዄ!粸&(az&,: s ѐ Wl5#ř]gzqp6ח^w}tita[6h:d4|mS%GY*@m&jRΙ?O]:i( Ub-5sy~I̵ّ1BF;vUM\=~ی\[Pټ A)(/r1[V\VWB!Rg}x9!b{衇;kūtn 016NqtÅ1it1kjds晉7p!zzzdJ0 caZ6W*K6uDB;evPk`)Z76vٰa5ۜ>}UQQ5ڕBSi5>HǶPahj救鯗ΥBiʱ.~ĹN1Ч0_xKfǶEqߤ\E9g!BLhO`0멪qikk#NϱXn6UXtl=hܽV8ϼ;8"Q:6nr8S<B{r1gȵ^]Z#2/:z<2Ds{xP(D-\~[:3 B1Ox {'D}}=CCC/8C_׊]fW7.wsuݴ3@ 0w^\.m;$B,Ҽ~z9rﺮO@xȑim!;fክg];c)^"q+ U~:הbI^fԆތ(?M;v;E_Y͎[ٵ1ó'0b o!sIV:P9zHhW7ɵi,?C|`rdW?~eFM= D0 *++) :rGQ<%QQQa!8Δݶ6FGGqݗ̏Hu-i~vb>:"* >cɛE[&~1p;m"t D.vv՛VSkip?Foql z~}9^ѕ/£E~lb6vNeCz+sL!}7oelmXz֮jq>b-TUUQYY9c+++LsP^^Nee%(6Bׄ$ ˕ m۞2[QQ1o`=G|ؕ-Fhե\=J2 Fƃ Ļ0w7Ph|E-~S[8) AbNխ}8|w,Ch;pnMF2uٰjo/ 5argN*BxݿXrR ؾ{EmՍB!n7CCCb^Y@ @,dSSSaxxx_;^/hX!-xwc=6w??^x5vy"siLgX9.zswQ_b{*cdSvf(5!Jצ OQVMnZ=ϱvXwp -^S-vgO02:6zo&)# -4tzbcccd2"B۞˯v1 C(" -l4%L&I&yLӼzo}avq\M,B`t:͋/=i IDATF9B*J՛w [1M*SI̜ Z 4PPnpxVzUK8D o8&w(UP.%:vDl]UM[;Ǟzj5Rb/s&vn۴ܡ,χ[0D""r"BԢ, JR 444~OCC?L_Fhz;¸u MwTod3M:PŚ2=Oqעu!-ofKsLw;CEΑLhrD&멤!ϥB3|<ViHW`5>]= !B!X|wB:&qllsLlp~/Mw(c tRS=t4"υF';O9}'[}3ДX^:?.GϩĞWccf8_ .[wm٠kX==@pyv:EG9֛aB!B~3><. \;U6lM4@M Esz;)g:YU K.(xR 7 .C@8iVih ۞Y/޻=CB!&/.3x6)Qə%Y_*2Z32Z<,)b;/ɮB!BNx_ SQ^Ww(?B!b>$]p4\9LN !B!ļH»"Y$_%Ѿq!B!ĭkQ%B!B!$B!B!nK !B!-^!^c:F;!B!MuS޷?򎥎Eq:wCB!b8p]xeWטƪr B!Ĝut q)E  ׃{ҷ\B!BܪyW^!nbT&K!_Zc6A? !B[ڍ|ޕ*B&r'oB!]IxM䋳'Ba #B!b]IxMX=LZHB!Xx7yW^!B!%IxB!Bܖ$B!-q;!+lK$Be.qnxJҗ;O~~SǏ}|- ,&lDg(w5k/y"7١BW!3*tW~v~E *ۦP̓77{_dV?.[k?(#] ML.n~f;_N]9RW_\x?Az'ri==00~ m=?EFU'WOX!% B!fUoڀ} ^hv;h*\\*5Tg7Θ2w|T1$w}A |y~+6 /~#j[N4_r/ORu w?xrb|Pl$/Y-'ŝ*Ld_|w8=hv?5a{?=tg>z4'Ɵ=?ƪe_? Jw*&bn}ۇX }S?hUÛSdzA<(;SlMeV7{P9qç>ۅcT3_Jv6`Bhݽ _8ãr+%UyWEtv=o'l& !MZ҄w p.SyQ<$,r4kq֪8ZJ^ hz/_uqA/wq#\{P# ~mq14kÄQxp!dg SԶ u8 !kL9T<]{y=ǟ8Ɂc^60eoV#''FV;2':}gnZK?>HgA#ڲ739!2o/mܻ#X֕9ŗy|lvZx)NluJ`(hs;cO«g9cj- G{i{va{gM0_Q~I#*}C.~0Ig- M7A\Iw˦zÌAuZX؀4 _`gBϼM= \?"!XKA>'4c>'D!N[Ԩ$.vj])^5kP's~O\먏> JE!Yj !x 5wEcM06ŞOZW_ejr=Oбy)~澗wm x>va+}Ņ~z{x$cD& ~ ? ]i z /û*\p. ÃE-N.~{| sG߇a}ta|W~0Crt?αIM?_ 3s޿EG6E8y !+frK/&`%.u]}ׯM=+C1PNv,4 30euUȻw/|ei{j3I`ٳŪf8PJN,x Mw? y_ )ю픊@͕mRt \n.(ޜ \zֿO}p7JН/="ԔC Gz/Ӟ>7q.FQ_Po^ !71JV1r=3UUGţUܱ6 f˅n`Cs?(ɞZ@񑇷}44kivhfKC1_O~/=Ec#_= b G;_mN-oJri⎇{S/[ !؂/XdwBS[9,L pG |$)&Q_N>pA{q8_JcQI!p>ƷzN~ߏ/䇾{'j }+Um0<|q8;XZTepje q/ 6}bq쳥$= p/88?>wpöBiJf@M._=ʅ=r>Нܿ?'uuIa3ɹCOo|~l޼*}oGk@8P{6j4 MSpϾD4_}7N&U-VTnNƶ}޹R}vRg D? u_<~6S򹔦]uԤʇ? g=S9L JN«GyJgW7 aڬ SؤI sRg/sb;Xַ"ohl? m#kwOJM zԹ,ZY b-(^7/J;ͩqs=M_[LN.`L\pUkJnjq_PQWK06T߉=5Ԁa(:X?5q̞MWf,n̶Z= cΤk( ԗQWW~ӮBI?y q";e(h~-ޙJ}](U&G؊ihkFЇpB-X(Z'C)0֯ۊCUW@Y5B1`,lEmI 3CQmB|) a36 !Q2-<6$)ܺdjs\PӝD`r"WCPR$RVK=ky{c7ecȤYcR+ӍcKY~Jf||mooX>Qx2 gyrJX[d0?Vj~j߉mYԼ~^0尣ֈ ׀3'C7/ AΔx.=aaZDt'0 rB/܆EMe!T0 ?om]U Y_~E zq~K }r#Zz2d9] {E386+աB!'p*Xp%q>ߘ{ÐJ7<5ڝLlb MA]yⓗ„ t3w孇ND IrNpxGp_!eNҺ QCDp쭀 ?RG/P?~6C#FxU055!q |t?zL<~3K n7@[B g#쩄΅Gomׁ忁Y F}afQ[NB!DX=ǔ>r6 ! HȢULL$3=?1#9#&Z\NꝫDžx!kˁM[ ѫ/IX[S(Mۨ;M6B,x袶kjFOniP~7 ͞琜d'zrc7g, \!߱lGE0!X#:;p-׾~*(YSaMpTM]HP!8 `1B!>ԝwޡv|M-y,6f.U\8;~CB;LJĪHE}KFw#IX-ů?ZsWg  M5d+^h!9Ʀ'>Ai!r:`H`@ t44?\`3v~#R 90H.RgTCˉr A6^"NH*B!Bw9ϻA_|z81)tF̜)v7X>g{UM/=0. 8gp}eRt1s>Q }rJ ;]y` xcuPSw5P9;|ՈcPS`( CݾQ;DYj|3 ?!B!%$-v: xS{ŗV?ٿ(<F)/7|`W[~V F\WB!B!Ng [)Ø4Öw v;``\*euu_ky!B!Wg6SrJeÞ4aOڡfFv2I[kOB|.,O]!BϗlKt i[=k[%x*QiYcQN B!1;hHHJsw+ 'ۺuPǸ7pNj*M2r3pwTqB!B!No xS:KDB)yXv>m$̩ vNoB!Bq:KH[`t`ɿߤW#2\|I6 &|z,\?1TB!BZBUm/ |˹0Qvlu[&CxWo ,Z;8y^6z; Pw@} S# UE+:>У\!(Y5 ?Lp* /vF?J [ _ %q,B!,JH[`T)#7mǓ/.[̟~~*LccbU'igAZ^O]ҬQrCwO{z`ԙ3 ] -IVK` !B^ IDAT񹐐7K52ë#\CT6 C ԄZ8cYKm=w*x44Ղ2xr$ZG.P1Zhj3wJԷ LT 6`(D&hlS2 V*$5%ΌI=4  0 pb` ;Zh@R&X!hk;@cUĕ If_%6„Qsr? :5ǯ=Z7tp@h>GcnnAEqA bi5mϧB ±#B!8e-0"75h_Tc>Bg-!~n]v>pɻ@ρqÏяB̚ }P u!]o g?47n}x)#Be RFxjWk΁QI1pahU&w8V 3:BRQLfxbzm ^^u,p7Þ6z̳\vpE s?P_9PQ?\*~ &_^~wӑf~h?DŞa7C\O> eC^aylB!B.!V7*fu$FNr7LZį/__={)'<.T_7o ^!~NmRs LA_CJȾ5k `si=砮B_GLɨo?栯 ow>Z dYu߹G7 Wm&:ej s_!zԷi}]N}]:zsSǏ!sr>gMB?'>?[8i]G!Bq$,f2ؓ"x{紹+%{ mک_G]zTZk@,%0lJ<(3!kV{ﵖw),E="E j]1x(~Q݊oO lwh-3{{͗#>xw` Z m6,@> i@tTA%`7@U`ToxWPUGxH%sa(A-0'c ,PL8la3>h,uPS`'Cê?G3,%G v?qځU̅TH/ llM:k!B!N4bUHmVr _K;rq}xޅ~x7Qpkߦ28 h;u3.? PSZg~a/L߅N9\g6%ئpZ8Rhj7H*${iCm΁0g~}藻Q?ϭ ?um5P mG@Z*߅oӮRpP`ˁI 44/ԭϟ}f __ :[8\ [*'#: 5mǎOk|5 LZ=B!B&/pU.x!:JDooc|xN7Vn4Q)@EJT/:PB?^^[#1y7>Rnx7Q0rvQ3ӡ5uZkz Zϗ5ʂoW{?Lj"6TG̅ ~fXQS).#kmU aPTOvzR= xkz5l;_E?y%ҽ@7ּ;E(} ]HY޲Ȇ A{>9ÀWC7G`ǀuY PpѯP#{xB!G]55̏ͩ4SWDVG?58@:@v.Q_[Gpoô*g(?FPMbek9eށtB?п~*@嗨[^DM K^斠O3 @OvCvo>`P_E缈U]v?{K;[kVfF}/J7Ƿ 'ˠ57n== PQr _XxMf8D2hɨkAUJ𞁚y X˷~G2;뷢nYذ5U@>LmYy*8jݣ3Pom+`cOB!]}]? ͻm` '%Rz{c ssvRQ,h[+`r,;^E^NE=wAu]1+s n 9ˆz.6HIkpZ| jq\^M/X";n=tY뺲ܶ}AWBccv%KW.m͂@:etCRаBrYk]@: =$ {!Ҧ#S x6D}kw⋀`;p6CӒ,~>oC~Jʎjynv=rRB!®% C=|FxoTƷ-҅;l;F'ҤL a JJ JT$x`:g*0Ntjfj?k:·:5 `W?8v@4dp : uiC1;t^~B/QE`eAUw0mCsYž _:cCYm>:>iAUΪ~B!B;%Y, tDQ1R>jN|԰MccPNdTB!BOS~fzSGDݩB}ʲ8y.x| :מFxy&ZzB!'BcѸuc!R U' է(]~ǩG!BqNʶDB!B!'MFxS¶mb`4ga`Y%҄Bў|:BO۶D"v8H+B$Y!>b'@kM$ɖnB!8mI+sӢҏB!hG^!FB!hC^!B!K !B!\W!B!B!B!>dB!{ b1֘vMB! jB|-v"T6O#{*y#hYy͡[BuX&\W: ݳJ2uUTGݤR4q!PVVƞ={ƶmͥgϞA,K !UW\q\bۘh *HVpfӇѓJ/\ɺ:7AzV\Gس}%+XQH ײlŐs'3)צp++DB^ge x pm۶QXXH(:Qss3TVV2d? !xI+8.VjwF"#7 Rʂ7Vnoz` [F|*7| [P]0  P7.+G714 enas{0`TW7䍷'4Db}zXױgN1[=Kxes/MfgObohO!Gz>ۍQ~h߻B`v6i cyck@&vE %^!BZ28"8>K`q⁃79&1, KS^[̀"u HJжCq]aHiK7x:%xV돼U ZkuX_wϞxWcw6!$fj7Rݱc`W)ucРAn*++K`B!8N!I)Eq(3r-G*hP[u N#I^QY Vyg!=.cmqqI>wzVb{Gͼ.ȫ)&Nfl{mb2NKB:; vuPCQ|n*^fAR mqjjj0M"555 >p8Luu5eܜGB!8u$B0ݼ#0t":T,d0p gD0,OꠠVe=4TS]<..vi_>{+ lM!ޗrw`;ʕK))t }SgW9h /st\+#ϬF0 F5oxq;AXXt2TuGN9۶53aY.׺ͥ @.OHQ=x'|Xswv&VR:2͏uè^skld5#Y^<.aJ]]{%0x`^/1hIJJ")) !SI^! xGtţ2 AIZn& kDؽz ʳqPzt0۴XS{).\m#~McCѦa }0ˍXaлwoJKKD"l۶UUUXEFFɒ@/B|VI+8> ,9#9h*#eXc5#ˏ PILP%k7cYw32D,8ul\DNlfvkuv}b?-?A?W7` Dh^YFT ݂cT4MYJ!Rwy 7GUPRVyr=m]p+4N,\Lx4m (ᘁm!8ء8ЏЇNFlO2ɾ6{:Q1mqc i1;ψM\.kꉺ?#XnnMQ"c#U%>Jğ&B!ݠ/pC=|ؕ[}QHH?*>gzwBײG(;~TlMUظ;c !B!D+Vb JJJ:6o @nn.Əc츱Mš)GpFzLB!Bτ2o<ϛOMMM^[RR«ʢ6}gL'%PMvE+1wޖ ^+s_0_D-qa[WgӿO.A b PJ_AOҏeeQPDYj>Ni޹a`6=8Xv j)Y%l-.ٛIAnNS9EE1/L1P(NQMz~Isc4h_ڟEHk3.\SJir հ ?^M&琮VjR/lBGjYzB!Bwݺu{g+V8rjjjxٵsgNg ja[Η+0H;Ɯi+fTΞ̞‡"$\?gf|'713ȳ''jWZLn?+;zZkz0۹aT2:lth@;yώl%~*|Z5r_`95₝D ]J{1{L&@y &͘Cq3R!79µvܗ>c_1LbU+yEOKGa /]HѺn-syLC5| EOo Y0kD6>={]iW8V M=_KEsEcT̳? | *c)?ZB!vnݚٺu+y*r\͏j_ndTOrtރ IDAT=Og|{oH.%e<5ws zuW]@}E5!Һta&1ؕȕ,ITۚ0" Rqcvp$ c .fj-;h?mT 呵XfΡ۹a 4IGj˅7ud ㊯MŢ7iJf:ӿ r4VE E\JtFWiGnN+=)RnY}|\Tdu'4Q@0tػJ˲pGFyR dB!8%,]be:555\2a{4|=rKRuVSvWOQdL&4T6?~>\^L f4tb%)9|bs;XϸiQ7|U)r?SzF+t83Bu"hwwneYVmׇ )H&6ј#t)@10-,C\vcyp1'XI ه8F<IB;1beCڴA;1FVÇ9.;@mHH v&ld N&O ߥZeaNˉ9MvPy=9][@IY͎#I!BDݠ/}C=_ԆR5g 9C_oײӅLxʴZ;Ltpu! y|/j -otoǗn?m)âK]azh6@&z9t'@z.>mWGm5L܆ !B!:|⢮46QSUΞM[9t B!B񹗐R!{ ں[!B!RBRj 8?Cytqꮽ@!B!i!1{8tq ~˻ts! !B!@B޴47ڋvvzB,fѺF~\0C9bRSSVB!BBB$pv$L~bp xB!Bt$!oA&?9W͠WC!kjq-B!s/!)] :Sn)Ss}/,]Ĩܺ!K2V𘋙k IAډ#ۿۜy$zy ܓ Ď>\f'dHJ&-5pPcӇ14w$//ǚ| g&f8}ضM,ql+:a`&n)e.B|n%&W@nn.%%%pu5|hXJbĜ>{FxcԗeZ{&h󵴜{w7^_b9OaN#{,fyQf0dA&aBԣG-C9/q, a6HDӔ۶ !7++q+ڎIgqǑuXp ,{că]``(2؅mvI:xLkvbDۍuYUKl Ll(0&nuSh}ݣr{Z@P`GGqc*@DQc9WDb(ˍuy3B!gNr.ǎˢ'JMMe츱'V]$a8Yf0smƦFh{U짧ֲ0xrGqԡdXsyc1\`SWY8F 'Mc\/JX".erI7XId llE3]+w68F`Kng({}؎6獦aU0MMIY3' bkv{K)m76=+ְ?qQә>,CYǨ^F˙aѰ]^_Ȱi\~e;ۿ % 3pE+X|ᢳzf3p4F5m׽[Rk2vO/G25->\abjEC{& L^M0g%b{K8g63\0.bVʍ1Izk;"uٳ9Wfy5=")[[S4#]\GI;Y4w5zL;Ş 5{\Bi&c8Cʡ(M&+Է{vhڻ\C;YIzʻ]і25B!H>>>c:ƍKd7ngL?r$?bVEm,_)I/L>CҸ L>k 8d"`N){bK 7 @v3l< 74Psƶcbκ(蛁[rgү_}nRpŚGqGCD&y-'T`&ŝՇ>ړMi9 hTI= OP$uHAZ%% p);CAHw)Pn2 #(agi#GCr~^xI_?& WZ.0M!"5T4Nwڿ`Feru;DbVwqr]?;slJՋ%˲l !P:lC  !@Byd[-Y]dJWm-[%5zeisν3{O;ƞI'#yP1S4*mj%vIW!B!x=uH$F9vX:6uT߾H5pmAvn#T:K9X~<0&$b$]8uk ~E,>VUx|B){PC6-p f?:ߏ=ζhL2~R䏪߃72.W) gG9ww(ssj?^~dcʭbkXit%>I,>|zX"1b 9SN}Ls&{õ&ѣyMԶ̬ @lV3dg ;6̦W3$c$lL$bI"y !B!^GWeE9sp;Mŋ9Bθ (p!%>ŘyU=؀ǻ(* CA(vsWYtr:]5U4|r0* oxT5Xij)H.3Ӻ9qKLL&)ō@w5•eL|W <{M&4cOobo-K*([EyC}ͤ,ÃX8ܚAJ?̉ uZEge31Mǎp$hȡ'ΠaN3}b39C*"J L4 cA,F>s{RIUUvb玝477_9,^E]jIyu ]Xs7k[j؉qǃ9I[hRMs _DaN]<-~'|'23m-_#:W6~5?xIH)B*M===TWWv4M# iǏ'33P(qB!8#]x)wn*otSyC^GA18!6/:pq Cs(y[xd?g0 ܸ3bue*rxwӹdBB҆/.Zu?<Joy,EB qɇὝ~e%Kൄ]Ů}CKi mmm ]b&SN6$B[x/ f׻oɶzM }iKmm@ƬDT危\W4GNɝsD+/.?UVv8sHx?1K`j`>$#Ëv$z P8sIscL%0j=ى>: ?NawIz^1;I(_v`'gGo@vV?FڝVE Z/U}5=x|#D/})@-ʆY@bzuO>,"??0hiiu]JJJ|bY8N!9 B+ƚxF2f-g'ٔ P\C?X|9n N垊]u{4jxgɻKųۚXtg!vs<У"r'?ś+}8矾rm)ǓXTv,5س(}8XZ>19>N$5ڲwM@~uJsz;}?fsC]Qs~Fo=,]`"=J6W;5[/<Eq^~o3>;t1}s]9 N܅''z WL&Z)~r-gVR>&M+gx0,T(xf9lC1ܲA L^ʡ/EbL[Jv]3PZSׯcz+K:u#}^7uR˜i&^y4k3;@)@N6A-Nc0g=k+hJ_;nΠfJa i`gBႦPJh ɓ'O&x]-1q!sB]464 `Zf>+4/< r PJHCC]]]:ujw7 RPP W! GzxMi\4+I lU嵺6īN6YP`-Lgjm<ߖڕ%I<(axv9|`roctG _f{<-4&;'B<E+ _?30pxGRiq=$|D£{B}g"; Ǻc=:D2F5֗I;I%nf5*ᚡY^}Hଶ&N15 :%r:{ ~g}I#պ=c,\|ח $Cmm-aH <L2L B!n8xIωcJtG^׳>I>ʗ3)#L՛]M^}n0K\ż$k8ԓɂUYcf1?-g>Gj}xp8?CWV% z&a(&cR p 2tG07^!Ä^=6 Ӕ'n10ԭ'9麟 3E[w{ M0EoO(R.LXQaR'C>nc9(~Rxt=֝Xk`Y̬~NNͻ^=۩EC|ξE]=3 kK>v7Sse&w&S|/ҋ'XxO)f/Wsb1gN7=ˡ`fN.O g?uӸOy;lmȄ1g&p <“Z`~*|x諟qMDZ &X}{0zA{ZO/met4J_|wV =pb=5 s qHFMZ12<.~bGká7OwO=!ct#dAxٵXС}?D=>,GF00p%m'%׋+օBwCK>4B7fx1/om$s8+ hgwḭy0U:WYj唐&8a+GDnX| fdqVed`&TLǘ<"cxϺG2FB"|I7f$/=B!8? B!o=1PvŢ}E]X!+" _[c 1dY!9#F/6L!8?eF|_!ByB!B!$ !B!$ !B!$ !u@$nJ]x^!B\ Bq4X B!DzOXBq0 CB!"Md^!躎Ų,׻IRJi@!!W!K/B!Dɘ)!B!^!B!^!B!^!B!,ZuK4nyT^ !B!5 RWWG]m-==tuu Hp$BYy9eees-:sq]R#C/O4ׯqB!BsMoMM eߞyLkk+ ??y 3w|**yKx3䩋"B!®jf˦Mlټh4zY綶SO}ˬZUk@7I^$;7.`>4z>A̦)P<| 5t 3G#`Ay'y7'Gtc/>|f*߅=P7LguN2)Y.oӹ߼n\ 2]5zB!bܹ*9Cs ۍxN~Gl3g|y֯Cq;$)d(ؾWq3Q*7O&cT*{)2]Qv7XV<\_Y9<794Ye·f/}=4wġ$ɾA]g`>%A M?r'yB!QoMM [6oNWqefjjjY}Ҙ`)xk53&^fU(m VsϡgR61X4HPn@*bR%Hy̿>-/N!B!xH^CW"w g{5ԅ,)gL| ɱ ~̹ee{/mg]8{J$ӧM'O%/1/B! -=s C1 Vh@aKGGeLBJє1j[JG7,71A39~[Е~9 y-sm3=&hhk|dYh@nY&zfeq!Jg;?'V |Ȇ^-/3iJB!b|R=ݻv}E~?L뙳GU:?t R}CbE ?(L~canlcĎKf_G>9MrA) C C*Gj53{]4,$=3xJ?'a3Kx {ў^[/ ?WMB!BKf &>W3U MbŒlIw4 bR ڳ.xngx_GOˉvxiu5 d^B kBdqNh1v1QVI0d,B![ZF^AsI WLmlUp/UUw}w7K-މ+?wW-B!BqiŪNvVT>FfJGGKZӓx/YY3A'&.$;m !B!HĴ[Ytaw9z_~Y]]]+;kB!Bqҳ@e}n^zUŚEW.IB!BqIK̼\e LX[t48UT$B!BxCq\Ue[7ײne)[`^^mXB!B1%𖕗lI7qkI#/hvn!B!]zoY٥<:!ux^d˪YthK*}u׾S{UkqHGhm?Huժ6]Egٸ pz8tlv}ݍ4&B!^erimm=;wک;xi,_!~G.^o~~Uh*au ٜ>~9Td郯8Wm!/xa쯥W Yfp^9|6ZtreXnF)%u/{5!B!--7''y SO_@&z)5vp,.pނ\V[nVǃL\x+hupДJG$1́\MC9))EWV2y0:F-A p$IKax=eNm8@N~ikN9^ڤn>xp5#)Kn4u4bY9Y$S6lx)9zμgb:5|#"<&Q:( Z$S{u;fA3}\d ^T!Bq}IK;o>۷|{vHp'\;JnДdX^NnHuJL8LI\ś7KitWȦc:֭aO^Huq\ϝD4pͬm f~4}lVMcN 9Q׍\\#K3-=d̆SG4Cg8Օĵ]H%" ӤuMr-a<8ŶM$kۨdn^='X`û9؃OfŔmyIWt{G;4cxrgrY%ZKlSɈFE'뺰\לeK< 8+ڏ"8+YTts{HMtIbB.\MC= Ab 8=u>),Oq0=;{ !B!/mUWKWjj***dQJXy,25;M H =8|Vlk$`5w@bKWrX%7Tr%,czϱwWo\/=l}ʕ쮣5QDHq&g~>&oY{ 8v?+)kmG,]Ǭl"ԂUܾqZvB4o ͙IW^b*"+B!u)?Zy̛?Uk\q9Wϡ@GΓ|eZʒmm͝΂yDdN*&Pde1“(1PYUXœSDo;1 E2(*/Gvnb\PC}Rjd :Ye$It4S4›]"RINEIFEoW vOfed}xձ)\݇pͽ)|  h )\e~NVq^ b˻NR U^IAkJ1< i (\F$MWm´B! 5aV]Ceee:=Cee%׮!Ǣb助[yaw ,<&Rx|&$;yGNf`P"U 5EgQ\$Hd5g$LugzHHm du:i`X*eЖxzTu$rtm`~1%M?7C7jF=O繱;5Լ>$IX$ |QHxQ>L"S3:N2AJ36^?"q+T !B!Ɯ1c&wW%VVVr[̌3T›]5wrǺdwCmTpqI/K]HTJFNQ4)>VmX#K$HdRrjn6ĩڱƤIƓ,29QUOk1)<}-4H&pofOs`aNc4I88Ixt/ HZ͊tދi$Hb$3úB!rU~Z 7SSC ?Tg =V%i'Q¤K{hX`318 bEn.kp+-ZXN(7B) /TkdN•,(imx1 I[wPF,kHI~In;Ehb2.sȡd IDATyB1q-La^5Y4E{) ɚL:߹,K'{2|`әvb YxS))N[MbJ~ ХG~i3mCsH9> oZNۧgQ^x|7.'&VP%!ϙ25^䆺c$qɠdb M|*"L^4;xct* ܾfjkP22 목e謧x'JW폛B!b s?tTRSS}{ٷg/tN~~>gWvd2<̑=`]AG ްe| )L|}X) σűm\_>1hp}v~Ǵu) ͮ(Mֱٛ] ]UV*A1M9]$Q:X$) 9@}4MìzwG* Lb9s^EՒj-SIܷ9ǣκv s}蟱ŅnF;c{DL5F@QfܛF-gqNYgrx#Z" }nXey|עt/>?R7C R4{5El8) tӫѫ1sgjRhs;@5FqJuoƸ^Jiޣa1?'0|ZQW!Bq!teNN999,\ZV{Ѱc[r-Ȼkt ދyI"XB!B"_޼YO{f3i-^gw"nn^ 2r-qB!KyRVRFt/'נ!B!D6B!B1.IB!B1.IB!B1.IB!B1.IB!B1.IB!B1.IB!B1.IB!B1.IB!B1.IB!B1.IB!B1. g^BFў׻ B!B\W!B!ĸ$W!B!ĸ$W!B!ĸ$W!B!ĸ$W!B!ĸ$W!B!ĸ$W!B!ĸ$W!B!ĸ$W!B!ĸ$W!B!ĸ$W!B!ĸ$W!B!ĸ$W!B!ĸd\ڨ>^Muu5ǫvG233̤rr%TN$//Z6O!B!8rMoUUvb玝477yLss39r/Y̢ŋ2eʵhohplw4u[#B!h4ʆg7qF.f{1l­oemD"im_5o yxpIt5r~OIf:9G 21ӠcI&Ϡ$pS474ޏˤ״c] L=F!BUK^`3عs#~}=sIS gϹ{0j|L|L1oJXAIpV1 ngI+yN$Fa/ۻK0v%BizIYea蘦^!Bq*0 ƫ?*XxAFG֓Ġ➏Y /;>ZVpMyKs}:dDQ/`odf^>Ӌ*0t' !B1N5qEQ6<᪄!ǎc3())Iۜ}ߞAÁ_׌oxlJ CB!i݇wóW>gRܹ nHKY|/dg=[K-`fpt:/ QC~̓G+n _ f !B!ު*6nؘ.jㆍTUU]Y!v+O~y4.%~@!S LcN ,lvs&@ :v5u6X0R5Y!B!ĥIې];w]CW];w]?|<x˃=4~V5}G2nXy\r7cBD[y<ɑiB!BqM;.c(fzϸܱo0)ڣp5=^>?|d%!>Ջ.Ώ})J)4uVsx-t:pm{| 8p!B!镖}GuvrzH{X%RX8e[qL&2N2ıyˋ'qĎEŶ$Rl")(6 ADn;?P`yAﳖg}Z}=SKKK-O]O-%䌙4L,{CiiiL-2bG})WðmEk?_uz$-5=&f?׾!fMц0=TR&X1"""""")1vBLwgmZjB׌0,lfk$e0~SwJ +HzF /[x6;`탗+}O=͑}{um/5fU}v ooDt""""""=>J+|?,O;zKw0K+""""""IH୘^1GxW91'3ybGOm吐c**&:M ,?cǾ~Ј3)mߪ8GhNÂqO9{ Igf仵4Țbp:A]IiOaBBscE#<Ksnd+%&N[(r?7_?yNnAA$mmBf nwOġ o@8FzJ"}tu `Rn8j\W:s'x6#+$C+G_DDDDD~~%$|r^z[*91jo`q=^~xC4aqE qgyD 8{q"8/Ưi*N$:N٫zcr0"""""rx-_]Lމ`ewVs;HK t>ro9n9ٲ 6"(Xm{tx߱YG޳w5D^́ KYNə9uϗLV|߷tg! 2#4Wmn< qH.GFW57<;6jp=#6GixE xޘHK?3S^{eQ6JY@o?OQy=oq>}O>ZF6l[Xst%14 ;Y%wpLLfx&Ndգf̘6>ѳe-+ZW$wmY$8A  QqUr>L, c~c%cnvk pqm\᳆`$ۘD, `$QTb˛Ɋ3mV1!|N'8+6 㪡>!+J8@` |E '&K&8m+Lmc0 }&V6=Ý9v$B \U`;I0  TF#@0iw$ct*񊈈- ￐;c ӣm9@,l&+{y{>vNiהb="<8‘Kec3HH8#)8;^O5R௰<SeN#a;ɓ Ɖn?9"ۑłAi,~` ޷=o&6D<펇Y~q:Ѝ13/c :~27o { l j_0cɻas6Mw80i]"ah,"1?xĢ1<:-""""r$tIN˗'8BΰiS( sWhqL)S H1 z43z2MS)SH뫧y"5)5 1|).)fm{sFFnzMy,#j8N`*K6NOgq/k~w_BKo)N<ޡ!觼phZߔ, La%LH/gj{ fVp~gL~/)f I]ԟ:EmZ&H[ĺoc9ixIZ}<03mkoȜmlgmTJ 0YDDDDn1>dffOJ#555:HՁ*ZZZn~PPPY||#%>BA2av Bp0}$^L ۼh<2Hĵ Ǟ;ͪ'2Hص n1;޿#MX~!pc(̭':8 \>ucbޥüZ'H5Hر i 'Mv89]2'⎁ev O<+` sr=s/DafP5 d!oabM p`'KL!ye'`${'YW;:\.?a[x⦻]ODc75 Lmia<:ɛJ6mDZjkk=SKWW̯S1 *W;}3,?kwb2Lk4$edi봈Hg L{ $]4+3qpcD_0Ho];j=ukXkgK Иݝ k8L° l4k _{=?|^Z> ҵ[krg'@vvII9K4IqW\rssYzl##^C Pl콝3us'y] VXM/CFl|7no ˶lƸտzWY9CZ7."""""FdR';܅vL?I)X 㭂ɧՕ""""""rOR{ܓxEDDDDD䞤+""""""$^')=IWDDDDDDI """"""rOR{ܓ{!""""""P{Hb1nJOO+"""@hM6uVzEDC """" 4pϟ۹xB{DWDDDdgժUl۶K.)􊈼xEDDD&Acc#ٶm ""w$b444}uե+"r)Lh4J,O|lܸQ7e """"qbXj>O^<{("rS$#hǏϳqFmۦ+"r(L;2{׳}vzED&$ #СC|K_b͚5رCWDd)^-oͷ88^x; k_]{EcȿWV^ͮ]Pl:멯. ==tJ(--ٽ!F_.%XQ|0AN}^cޯbu{p]]+8tVGQ" IDAT7ݕ{Y9̑CikkL[[mmm //EKpbF7__<%%%lٲo|k_b6~"QII ===޹ݻv=kxg[]ד6)tکog - IS]wLbJK[C=6Ŕd1(M4vyN)<7xnu-s(20ǻ~N م(Mc =~x\lҧRbt57Pw)Fr~ ;S^^ζmHKK?1w?Mcc#+W+""5iڱ#Q=ݼK;wu3{pH0نe|8'Ymr?r-?6u'7E}If#~pf`e?|u5PS938ԢVaLyoշE'yk)Ai=D?ĺ7yeAoy/pó|YȊr1c[n__27?>xd,K?5LIٴKwv:r0'OHXDjwޤ)agMg3;Ōyl\Z,qOǔ8;lzd=K}sGSȃ/BNo̠Všֱ4P͞fae%sVnj^wتkz<xaμo{c=)h;vZDDN?T{9 7Yz5G%߼"m  Z^y%.|+[ޱ%{o1sǢci48ʏhm#xY#_-/3{.# >1'HlGݗޠ9~Ҍ5.L~9~snf__geLby\|mf^\RTź<˳DĨnڼT? ~kI 2gݴ:}W38ÏcfΜҥK ݻO~|_e߾}200@RRƸSȝJha׎vGֲkN HW'}.:f (δ^?;銸`x XWO&S2)) MIA;9$ <\+1-ȧr*x8Ɏ>D<|+WwiC{~?~m-8r07/x=v![>s|lyOr c_FosmbOm~3u.ii С~ Lcyy7s LONgY<Îm{9\%d&00ͫz k2>V*yAbSu3}=}R:i)[k(Mp1xkٛVR fSq}z*X;ݖ޼yБzۏՍG6~uţD]uNx(Ѹa]4 i |6q1G.pdQ"+x`E˃BŻo-i9qudSBsw~t{/[‚ؿq뻈{.$`VMǪHF(3!6C2 ;b ''` m`fSrR<ƒf4Js%TL~i(\CnGx0 vJ - LygGh8EDDDD.Kiii۰ޞjkkY mXOZڝkee!;ΚCar 0/8&q+Hh>Mv 5>ą0V(P&wc //5 ӏLF ׳ctz F)1?`a _S\ %Cs#7Jw0+p$g- x] 7OJ&d[Z}wyNj(E| 1 ģ13y0|G_ m(p+gs%cc 8 5IDDDDD&,̞=W^|)ᡷ-{b;gϪ`rD!NaA5%Xp#x>04n"qIZN,3"ݖ< o=t{8KXдkM6N4:&p9ĢJ~7w%.F4? HIaL D.[/iiƞ4Of֖.qǻ)X~u{b.v/!;fi'&>DqJmDQ.4_~Lwvo5|7`X>,Gfn:NKz#ĹΑ{p=|x7:f4RȡsqBӖbKM-YPyyKXVAΞ B.x1Vυ{'HnN2qnC7;y|n9/FQ$ 3h€;ϋg7%D psӴ´Wé*{\gxG̞="ؽkmޜuX>1˘rϰbspyYc2 +PP3y|SNQn}l3Pm{8Nf0)t)ON~Vgc|7Ѹ~l*gg`I+R6m. (Kn{8Ywee_lݯppeMZ%$] a$duu;Ξ=#9r0mmmtM^^,fwxNh4c|Cban {`6Ab=s׉03 ,ucD"q Cϸs}cqOo1Үu#8.#>3x|n,Lı|ޕ=7F$`Lr<0Lq?e /l=ɑw ,pDֲ"xh_oyiDh>)0;X8 F4B$8x=X5l,ӣ`bHgmqsDx܋ 0IC$ `CJ"d"޾ /.,6EDDDDZ:nX /ԤI/|ዓ7;Vyy9[:멯{h׀ RS(-+Ҳ2'o#0vMk0 @ҵfH9^s/y9<_Ӯab]Ua7}F8˸ai^۸mݬ?9<'&u,?,g`Wa^9>B~E@2%`X՟hC\?`h.@f q.+wDvv6,]n6+w >׸"""""s_TŬ˱)~ 'N>)eX_⿅ DDDDD-0}!], $_$0IwyoL${DWDDDDDDI """"""rOR{ܓxEDDDDD䞤+""""""$^')=IWDDDDDDI """"""rO!=-ꇈܦ޾ """""?4+""""""$^')=IWDDDDDDI """"""rOR{ܓxEDDDDD䞤+""""""$^')=IWDDDDDDI{݁_*w8 aF:4{ ]8L+ X93Y ]v5a ϣb.f\_ v7K9OE^o鿱fR1R?7d<ޮHݕ[SSTe2---p) Xb9˖/nt.`n;v]5ռ; -O.'A ݫ/ IDAT-3xÃ|,oTf'_z'z<6~1 `LOvmY8G^} M];k˕xX|:=Tq SJhI_S9ZBsx(5[w?PFHŬ?22k m;m82Tcţ~ʜFiPj32(M78 M{+ÿoN~mq uGq 躷ib=h7HaIAi3cx;}۶ǝq߳'xVCwU2k8Y˷wZ2M 4c=o[_ȁy\(8տ>M M7}s#i-}muY}֒d?|SVob+g޺?ZY=E4$DDDDDD.}=!4SuV2X>>kXfX|-&U|wL0 mZ&ab,1[G NzZ}/|`·+z9SW[]ғLLü&մ-,^mQi>ϾWb9 ;`Ӟiۘ5­"JL}8que LOk;Ŏm;x}q&4+ewt]}勺BH$Ur [֛)B!Wى1z=s+1wQI4gNH \\r@tuRt}2Yvmk\ }"t"X6kx]6SJ:.hN1|NJE&@ 0ɊHXꍍ:krʗB!1D2I,'L`X"ohY!B!wIxӯ|l_bO}v Yv_ZZ -B!'I"d8G$y/HJ ɋ/ѽyfs}K+B!wD2I8:J4:eؖCt4N8::oһ o⊛:?cR5;s;lw*וB!B;G,'&Ibs| V\g|6NN uFtm_s8uߌ-{c7nw{(/ͰqD s~;ڹO8qǻ8tu},jfoB!Bܔ.'9?_U+WGg5=`(v޿凪u[ݢ^v:+XQ近5nw6JS mq8c/H0p mZVXnڂ-/ÏN{HkEFM-gýwQ˖ygizZ])i4ΫM`zIcN-n潷?uEWmn*v EKm``kToɺ>>xi7FP~'XxO+e+4fl=~ȿqvuqE,Dp=N ci> n*ӝl̇oΩ,Uű< ξΏyRxv24v\_kwlciڕJv](x0Tybd.UQn,V"Qe'|YB!B|L-X[YYɎ;x-TWc*++ox)NG+xӵdj.Vt(.S}w^$>+VՙKYTn+0Dv> 97щ::@䞃m (mwO ҭ69Q>$F98JЙ@<``٣ܻiZ&%ed}Vj}GujKF7ЧwT{N4䁥lxx+]qw B/c'ws>3%4 MkHMp8jװeg!GQ (*An',}ӬHp1 0;X;GI0;\) мm( 'ZoОҲߦqpLJy-Wo=E!U"8LX5{<Q}bV\NQi؊}>ab3N Ç rܽ9ŠsǏ f]wʍRf]gJn,Z/-).+x0z%H'}^JҸdr!B!n|Ŋ<<魪zz^懗qwcmHUMwqM/uy|x~F0mbmГ4-5mxfz$Y39i'.'a7x?{qO4bq\o6)G9 _g; K{8wG ?e[&1Hw8G0k`4@Xeǣ0fϰ,ezN_Pê9V+w]\,U \FNJڸ*S\줅sEaYdAѧ;ϦXIlEҗkÔ+k'I:*1sq:wyӏ倦;L(:+9V SW!Bܙn0DBkops&! ݫS-iͽgmFȭFۨo$,g9ѢQz1W+R S R0+{9UMΪ<5:P2iyGή ;~{kXn3cָ̹'=ҕ,g;کtQmShS}  KgF]{]͚ @}}6(X^$={@!.]Bײ"a.=`*V'nOЗU%^멿0HH)\BMY:&. G9)&g|AK'ѓU>b9=FIKw =g)kdqy|?Iϙctɰ!&Zh2V,+$(]N{PfdPl ~7- $Aqm%@U, i=]Gۈ8خNz*ytS2@qP,+{Dh?EKT=lX*jrLpct;MCOl,=e~B!7ͻ\b%%%oiiiعfT@oFB7] S{1Ì-#+|瀅koY&*#PC`bWTYuo 6u.'C<%lgݻ_继tǢ9@/Ы(يJYu!gQQRkXZeSy}|琇Ma,1L•8:{ٶTo喱0ԉlkCQq:ggomfRB XC-o"-Tcl uPmXJ-(.ןa8YJMBoY:G[9ʹӗPX㷍3:Hg'fj~PQb*@#Z*XMQ*Ghp*Ec p%UXg15Hu؄;,Z]ٞt%\?z'#gI{m6y+6RD:9{ kXkZno?u0ul{,Y>8߀UM(@PU*34flS)!b/ZOR;j6ᐌq}* tE]_qcTZ!W/!P};zU+9t?8Hgg5 Y~M<_v.I'>ާX4e$qR~`+Qx{'d|'h٬SK'AUl~|b$0yi\+e$Fc$][}WdOLeѶ')/_'Ǐ:T/ON)SjdxO-T<^m<]N[{ЦǭYmƑø^ŊLj+ oJ;?UA"'i>/xe<]^2.i+f8I~z:}z@xm<񤂦'p)1}%< j]<^a4n{u/'<)h@ݏt `x+Q}dwLb 誄dEOf>YF0>@{꜂O\%0YyG7E3ݜCv"mi;[?Ssy[)A^{)MQI,ċHFS* &5UǕ_VЌո-Nxa3Sjp]4Zhj> &%UT)"d .EɤaLYHL51u^'I@NI{S2KPwb?QW,wUov1y]g?MUPgUUW!QǙJ4qiGQ דEŲTtAAIUşK~ŋ)ԁN4 @2vh)Gh<㱨Z9+B!wgW~kܢFqPRwM~O?83*6c(ڔ}b]ǁ6jSu lTt@RAl2fX$6nG;1OcN:خvg7~^^%ܝZiI:#&NЌ}s'p IDATH&m\Uǜ_L`c+:O#4#h-ƴ6s+BQ4ngwE?^!U4uƪ(Ҋ9k%(ݜcq*ef}st)BJAd@1=ZSLSIEeV~|8GQg/hƜa)qyUiu͘01#KzE!N% X6Zz9d/a* .ZZC_B!Ǜ$B>5H5:J3YKX`YIlGA7ͫX !B| H+ӷOvS() ,]WX!cHV-B!BqGW!B!I^!B!w$IxB!Bܑ$B!BqG=B!B,aodqI!kWuZ;4!B!3 ܫ{(+ލDc1:G0mp^!B! b:ʋ y sΏRw/)~?'5y+B!bAt PYZ82R$2٦$B!B!D<4YF2ix$B!B:oa! B!B$B!B!L !B!#I+B!$ B!B;$B!B!H !B!#I+B!1Ox]gw<];!B! ILKK -͌ 388.B!RC!h"ykJ4ڣ_)@-~DcC+ ʇB!'(Dc1>C#X PYZH8:޾qے655qQ9JwweyrrrXUk)//59XUzK2>.D,gu;!B!OL;{ٸu Tg߶xni;<<̻w= ]׹ݼʫط۶uvRSS8BmwŽsIVQ1iO'@%.tWS-.$3Y&9KwB dbsPA)2=s=D]Yd[y)-hFL66øLJsI3>&ZQ.vd(?in}]#wDPi{n{#;t/d.V =  >y]7ӗxKHQ7E#=E,r\;Knm/9EELB!Cr=LYQ?v/PYRH[WZxd-Kxn=zS ҋ/ƶ{S]]@N/o6g?lⴼM)&>ͳ%[s/~ar]I;YAS?y];j}=>V2H[Pʼn:46|W̱3sx|{Io||vypd/ ^D -_yZF!m/~9Y_1Jz3בIS뭄'OTT&;Bxy)$|oަ% ܛyWNXWM@?y&P;666.t466 /,Hˁ[g84k`pIa k]+ Yai^rrz1/DDcAiÑ/,-_d`Q7nW`csW"@W jaol #rQ2Rž.'9Ͽa. K)CNı\ O[½bƏq`îByr"LJǯwRw"+Of#tU^DJ\"Uuޛ z\Ȩ}OU ]ԽʹM oXBO|B!B\:;Mx[Nhlld;),,#_>2s> ojiv,F㥰!hzoZLSAq.g֒1}:qF-=ћMe[N{0a yBdĒ뿼B!B;Ԃ%ǏnǏ]d,C_揾ȺtZ{)i0k盗t՝-[Wrb>x"?XNe(@W燫<2Kpoq~p c+KIvȒgOk w?ȯ2gOmUW(dYMg咡PrzNM۱o]45EY˿g*_#MY7hjdٸ=h:RzT g~Y֖b u8H~/W!B1fAViؑʬh1esQnyhy[_}>b>mKI%d*q۩ ;Oڛ.x/?Y_Q&(hi*LJV54EEQnr1&|z\3Ja5 jaԗOˆsx^

W~~Vd xD TR&2_|7O)ۄX[-ʖ匒֗eMI~5ѫ>]!B1hpA'+sw*":2S?[vkS$9!P<~> _W¼[B! B{'W􏍄}k0S[ZZnn^Etx=3S<ÛB|3dU@!EEØz5UYx;iV:yG5||W*0?xW,1GsXZ~"4{cCEy _ WB!ma慨vl -pd1y+^ v-{!B!Ȃ$÷qFFo K e—SɖmT<4q=lKs+XX !B!<$Ὕ3488x'KR]p H[̖lCB!Bf臹X{"B!B!>~$MKK[jnH($ !B!mA`0u!! !B!Â$B!B|t-L»hBTjb$gbK\7'f>k;ŹS 'x^y+B!X8 J2rrr)XfsFxm"}X%TzoM.'F%U)8 5;,8K9I[T#$či,o;^NuYo=B9CQo>74B}iPU1]uATcoաn 8(Xo-Ψ^Vma]i *pI:F]śk9}7 b bԤspv:gW pdI:㠺6{԰r%G!PM+ )I:CsbBhp\e*ruGURJ(OۿKB($ǡ㱦RnxN6UoaUp N7tu4y,^5E{8O~uV)jdVQדǪm(βgO/" 2G3~/VmfMI%B!Xh 𖗗u6^zūiukomT4e.0Q%B|lJK5xhs J{q|۪fPXl99b8т8)Гt͡cMdnYLAMj.sUd8rI3ξ{g(XI;L[Ow{<}Ed+;tHEys7 #V7]|U^#`cX ⫹ hs쒗۷S< TzZl 55mlgdxƅzREENje.cfOc#PWE1; _(qtthۛG1 ކpopFKdZqKULqs͋t[g5B!B|4^\𤷢Gl`fTPK< *&]8ab\i gUbs$*At}{1>#uxa3RMJ7m"0#Hf34ݦãab۪_[蹬aOV3B\hW=D`MMd閍 G05DˍM2O1M 3w%[ksrĎFICFF:  CFwg;M/ ]ܪ-G9x<{u_m;F,y-B!ĝ疬S]]#?ӛW.p >䐟ŵjuutaN6~M:¬wT} 63j 28Bp0 ;'5X@~`s.N"H 00 c|5eXmgiHߵ ,bdhMdpB.guC|b065IlR\N̂LKgiCjΰB.jt^ǻx=VauvmduQzP~>e P | ؄Hb;N}Gtw4$ȥ:N7hgN{T0B!VX 5QTTĻ{\s BlݶfTpt t6sٔA]@ eG-j6V0DSlީ-h/Ȋ~":.z ]NNY ɬ(!g(z貖Β +8›/BUqu2m9h sݗ9j(_{I)* `jC5tl̥l(NJ K9ڨ.kR>֦i+^͊%N*7L/C=9/s uP|7O!-+((_I}sYT]Dok$9]]oU9gf.[Kl `"B4^}|o5EA!^(}@λmgiي-`>y\ɒӜr;K+4? ^guaQNErӠq6S7F1ѓoGc!B!^1$IXKP57w9r+9tw@όqvzONi{Ә(Io>ya0ګa.̞Ї7 iƚwQܛMI-QWqvo2=IDAT- =|0Fy>,QFo .S 1{^W$a(ӸNF ʱ,i%wKdID%XWPf$6agI7qeq0u6f 0N1ٍc^1֔4U'N Ǧ.1^qwzGq|=HK6r { M"B{P{[-r[@ҦzTRV+ O7^6W6!B!xI*XjGU:uի_ o$\,/-̯aj!4 M[2))B'X*[71qfpN;,."Jm-9%׋1rp e<iwʟNi/֩1R ܜx+O C"zX )fϒ-8C9§`\KPz'[+BidJX{rB"ǧ dB!K&DaHϺ~[:zsorujj_?6FZ<e?(e!B!zrm <|嵂TeM13j\ p,Ɩ$A飧G$qLlC4>_~B!xm)x݀9U-[ gސqj_ $!B!ěؠVGO["B!⿷߻Щqۇw~>!B!of@]|'B!Bȵkߨ ] bIENDB`linphone-desktop-4.2.5/tools/000077500000000000000000000000001376717241300161605ustar00rootroot00000000000000linphone-desktop-4.2.5/tools/app_notarization.sh000077500000000000000000000043351376717241300221050ustar00rootroot00000000000000#!/bin/bash #Notarization for Mac. Launch it from the build folder #rm notarize_result.plist FILES=OUTPUT/Packages/Linphone*.dmg for f in $FILES do linphone_file=$f done echo "Uploading $linphone_file file with xcrun altool" xcrun altool --notarize-app --primary-bundle-id $MACOSX_SIGNING_IDENTIFIER -u "$MACOSX_SIGNING_MAIL" -p "$MACOSX_SIGNING_PASS" --asc-provider "$MACOSX_SIGNING_PROVIDER" --file $linphone_file --output-format xml > "notarize_result.plist" echo "dmg processed. Checking UUID" request_uuid="$("/usr/libexec/PlistBuddy" -c "Print notarization-upload:RequestUUID" notarize_result.plist)" echo "Notarization UUID: ${request_uuid}" #Get status from upload for (( ; ; )) do echo "Getting notarization status" xcrun altool --notarization-info "${request_uuid}" -u "$MACOSX_SIGNING_MAIL" -p "$MACOSX_SIGNING_PASS" --asc-provider "$MACOSX_SIGNING_PROVIDER" --output-format xml > "notarize_result2.plist" xcrun_result=$? if [ "${xcrun_result}" != "0" ] then echo "Notarization failed: ${xcrun_result}" cat "notarize_result2.plist" exit 1 fi notarize_status="$("/usr/libexec/PlistBuddy" -c "Print notarization-info:Status" notarize_result2.plist)" if [[ "${notarize_status}" == *"in progress"* ]]; then echo "Waiting for notarization to complete: ${notarize_status}" sleep 20 else echo "Notarization status: ${notarize_status}" break fi done log_url="$("/usr/libexec/PlistBuddy" -c "Print notarization-info:LogFileURL" notarize_result2.plist)" echo "Notarization log URL: ${log_url}" if [ "${notarize_status}" != "success" ] then echo "Notarization failed." if [ ! -z "${log_url}" ] then curl "${log_url}" fi exit 1 fi echo "Stapling notarization result..." for (( ; ; )) do xcrun stapler staple -q $linphone_file stapler_result=$? if [ "${stapler_result}" = "65" ] then echo "Waiting for stapling to find record" sleep 10 else echo "Stapler status: ${stapler_result}" break fi done spctl --assess --type open --context context:primary-signature -v $linphone_file #validation_result=$? echo "Validating image : $?" #if [ "${validation_result}" != 0 ] #then # echo "Failed to validate image: ${validation_result}" # curl "${log_url}" # exit 1 #fi exit 0 linphone-desktop-4.2.5/tools/build_qt_rpm000077500000000000000000000030751376717241300205740ustar00rootroot00000000000000#!/usr/bin/env bash # See: http://wiki.qt.io/Building_Qt_5_from_Git # See: http://doc.qt.io/qt-5/configure-options.html REPO_URL='git://code.qt.io/qt/qt5.git' QT_VERSION='5.10' RPM_NAME=linphone-qt-${QT_VERSION} REPO_FOLDER=linphone-qt RPM_FOLDER=rpm-${RPM_NAME} # ============================================================================== RED='\e[1;31m' NC='\e[0m' SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" cd "${SCRIPT_DIR}/.." # ============================================================================== if [ ! -d "${REPO_FOLDER}/.git" ]; then git clone "${REPO_URL}" "${REPO_FOLDER}" fi cd "${REPO_FOLDER}" while test $# -gt 0 do case "$1" in --clean) echo "Clean..." git submodule foreach 'git clean -dfx' ;; --*) echo "Invalid option: $1" ;; esac shift done git checkout "${QT_VERSION}" if [[ $? != 0 ]] ; then printf "${RED}Unable to checkout ${QT_VERSION}.${NC}\n" exit 1 fi ./init-repository --module-subset=default,\ -qtandroidextras,\ -qtcharts,\ -qtdoc,\ -qtlocation,\ -qtmacextras,\ -qtnetworkauth,\ -qtpurchasing,\ -qtremoteobjects,\ -qtrepotools,\ -qtscript,\ -qtscxml,\ -qtsensors,\ -qtspeech,\ -qtwebchannel,\ -qtwebengine,\ -qtwebglplugin,\ -qtwebsockets,\ -qtwebview,\ -qtwinextras,\ -qtx11extras,\ -qtxmlpatterns \ -f cd .. mkdir -p ${RPM_FOLDER}/rpmbuild/{BUILD,RPMS,SOURCES,SPECS,SRPMS} tar --transform "s/^${REPO_FOLDER}/${RPM_NAME}/" -czvf ${RPM_FOLDER}/rpmbuild/SOURCES/${RPM_NAME}.tar.gz ${REPO_FOLDER}/ rpmbuild -bb --define "_topdir $PWD/${RPM_FOLDER}/rpmbuild" build/rpm/qt5.spec linphone-desktop-4.2.5/tools/check_qml_syntax000077500000000000000000000022351376717241300214440ustar00rootroot00000000000000#!/usr/bin/env bash # ============================================================================== # Tool to check the syntax of `.qml`/`.js` files. # ============================================================================== RESOURCES_FILE='resources.qrc' LINTER=qmllint RED='\e[1;31m' GREEN='\e[1;32m' BLUE='\e[1;34m' NC='\e[0m' SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" cd "${SCRIPT_DIR}/.." # ============================================================================== if ! [ -x "$( command -v "$LINTER" )" ]; then printf "${RED}Unable to find ${LINTER}.${NC}\n" exit 0 fi "${LINTER}" -v 2> /dev/null 1>&2 if [[ $? != 0 ]] ; then printf "${RED}Unable to check qml syntax.${NC}\n" exit 0 fi printf "${BLUE}Checking qml files...${NC}\n" so_far_so_good=0 while read file; do $LINTER "$file" if [[ $? != 0 ]] ; then so_far_so_good=1 fi done < <(git diff --name-only --cached --diff-filter=d | grep -E '\.(qml|js|js\.spec)$') if [[ $so_far_so_good == 0 ]]; then printf "${GREEN}Done. No qml error found.\n" else printf "${RED}One or more errors were found. Please to fix them.\n" fi printf "${NC}" exit $so_far_so_good linphone-desktop-4.2.5/tools/private/000077500000000000000000000000001376717241300176325ustar00rootroot00000000000000linphone-desktop-4.2.5/tools/private/pre-commit000077500000000000000000000002671376717241300216410ustar00rootroot00000000000000#!/usr/bin/env bash # Check QML files, quit on failure. './tools/check_qml_syntax' if [[ $? != 0 ]] ; then exit 1 fi printf '\n' # Run unit tests. './tools/test_qml' exit $? linphone-desktop-4.2.5/tools/test_qml000077500000000000000000000035631376717241300177450ustar00rootroot00000000000000#!/usr/bin/env bash # ============================================================================== # Tool to run unit tests on all `*.spec.qml` files. # ============================================================================== TEST_RUNNER='qmltestrunner' RESOURCES_FILE='resources.qrc' TEST_FILE_EXTENSION='spec.qml' DEV_MODULES_PATH='./ui/dev-modules' MODULES_PATH='./ui/modules' SCRIPTS_PATH='./ui/scripts' RED='\e[1;31m' GREEN='\e[1;32m' BLUE='\e[1;34m' NC='\e[0m' SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" cd "${SCRIPT_DIR}/.." # ============================================================================== if ! [ -x "$( command -v "$TEST_RUNNER" )" ]; then printf "${RED}Unable to find `$TEST_RUNNER`. No tests can be executed.${NC}\n" exit 0 fi git diff --name-only --cached --diff-filter=d | grep -Eq '\.(qml|js|js\.spec)$' if [[ $? != 0 ]] ; then exit 0 fi # Check all `*.spec.qml` files. so_far_so_good=0 while read line do source_file=$( printf "$line" | sed -n 's/^\s*<\s*file\s*>\s*\(.*\.\(qml\|js\)\)\s*<\s*\/\s*file\s*>\s*$/\1/p' ) if [[ ! -z $source_file ]]; then spec_file="${source_file%.*}.${TEST_FILE_EXTENSION}" if [ -f $spec_file ]; then printf "${BLUE}Running unit qml tests of '${source_file}'...${NC}\n" $TEST_RUNNER -import $DEV_MODULES_PATH -import $MODULES_PATH -import $SCRIPTS_PATH -input "$spec_file" if [[ $? == 0 ]]; then printf "${GREEN}All unit tests have succeeded for '${spec_file}'.\n" else printf "${RED}Unit tests have failed for '${spec_file}'.\n" so_far_so_good=1 fi printf "${NC}\n" fi fi done < $RESOURCES_FILE if [[ $so_far_so_good == 0 ]]; then printf "${GREEN}Done. All tests have succeeded.\n" else printf "${RED}Fail. One or many tests have failed.\n" so_far_so_good=1 fi printf "${NC}\n" exit $so_far_so_good linphone-desktop-4.2.5/tools/update_resources000077500000000000000000000020651376717241300214650ustar00rootroot00000000000000#!/usr/bin/env bash # ============================================================================== # Tool to build automatically `resources.qrc`. # # It should be used sparingly, it adds all `.qml`, `.svg`, `.png`, # `.jpg` and `.js` (contained in `ui` and `imgs` folders) # in the resources file. # # If you don't want to add a particular file, do not use this script! # ============================================================================== RESOURCES_FILE='resources.qrc' SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" cd "${SCRIPT_DIR}/.." echo ' ' > $RESOURCES_FILE for filename in $(find ui/modules/ ui/scripts/ ui/views/ assets/fonts/ assets/images/ -type f | sort) do basename="${filename##*/}" extension="${filename##*.}" if [[ $extension == @(svg|png|jpg|js|ttf) || $basename == qmldir || ($extension == qml && $basename != *\.spec\.qml) ]]; then echo " $filename" >> $RESOURCES_FILE fi done echo ' ' >> $RESOURCES_FILE